SQL文についてお聞きします。

以下の様にテーブルがあって

---
日付 商品名 価格
2010/11/12 商品A 1000
2010/11/12 商品B 500
2010/11/12 商品C 300
2010/11/13 商品A 1000
2010/11/13 商品B 400
2010/11/13 商品C 300
2010/11/14 商品A 800
2010/11/14 商品B 300
2010/11/14 商品C 300
2010/11/15 商品A 800
2010/11/15 商品B 300
2010/11/15 商品C 300
---

二日以内に値下げした商品を抽出するSQL文を書きたいです。

SQL文の書き方を教えていただけませんでしょうか?

回答の条件
  • 1人30回まで
  • 13歳以上
  • 登録:2010/12/27 01:22:20
  • 終了:2011/01/03 01:25:03

ベストアンサー

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492010/12/27 02:43:38

ポイント35pt

【1】

RDBMSによって記述に微妙な違いがありますので、とりあえず二例あげておきます

いずれもテーブル名を Q1293380537 としています

下記はいずれもWHEREのサブクエリにて「過去2日以内で近いほうの日付の商品価格を抜き出し」て「当日の商品価格と比較」させて絞込みを行っています

(下記以外に総当りで求める方法などいくつかの方法があげられますが、考え方のシンプルなものを回答としました)

余談になりますが、どのような方法であっても商品名と日付での検索が高速処理させるためのキーポイントとなりますので、商品名と日付でのインデックスを作成(CREATE INDEX)しておいたほうがよろしいでしょう

(1)MySQL

SELECT *
FROM Q1293380537 a
WHERE (
    SELECT `価格`
    FROM Q1293380537 b
    WHERE (b.商品名 = a.商品名) AND (b.日付 BETWEEN adddate(a.日付, INTERVAL -2 DAY) AND adddate(a.日付, INTERVAL -1 DAY))
    ORDER BY b.日付 DESC
    LIMIT 0, 1
) > a.価格
;

(2)PostgreSQL

SELECT *
FROM Q1293380537 a
WHERE (
    SELECT "価格"
    FROM Q1293380537 b
    WHERE (b.商品名 = a.商品名) AND (b.日付 BETWEEN (a.日付 - INTERVAL '2 DAYS') AND (a.日付 - INTERVAL '1 DAY'))
    ORDER BY b.日付 DESC
    LIMIT 1
) > a.価格
;

上記いずれの結果も下記(順不同)になります

日付 商品名 価格
2010-11-13 商品B 400
2010-11-14 商品A 800
2010-11-14 商品B 300

 

【2】

求めるものが上記ではなく特定の日付だけを対象とする場合はa.価格だけでなく日付の指定を追加します

(1)MySQL、PostgreSQL共通の追加項目

) > a.価格 AND (a.日付 = '2010-11-14')

結果は下記になります

日付 商品名 価格
2010-11-14 商品A 800
2010-11-14 商品B 300

 

【3】

特定の日付が当日であるならば下記のようになりますがシステムのほうで日付を入力させて【2】のようなSQLを生成するほうが扱いやすい場合が多いです

(1)MySQL

) > a.価格 AND (a.日付 = current_date())

(2)PostgreSQL

) > a.価格 AND (a.日付 = current_date)

結果は下記になります

日付 商品名 価格

(質問文のサンプルに12月のデータが無いので何も返ってきませんね)

 

これだけ書いてAccessでしたなどと言われたらまた手直しです(笑)

次回からでも結構ですから何を使っているのかを書くようにしていただきたく思います

id:kamesann

長文、ご丁寧な回答ありがとうございます。

SQLiteなので日付形式がありませんが、その部分は修正して試してみます。

年明けになってしまいますが、結果ご報告させていただこうと思います。

2010/12/31 13:16:35

その他の回答(1件)

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492010/12/27 02:43:38ここでベストアンサー

ポイント35pt

【1】

RDBMSによって記述に微妙な違いがありますので、とりあえず二例あげておきます

いずれもテーブル名を Q1293380537 としています

下記はいずれもWHEREのサブクエリにて「過去2日以内で近いほうの日付の商品価格を抜き出し」て「当日の商品価格と比較」させて絞込みを行っています

(下記以外に総当りで求める方法などいくつかの方法があげられますが、考え方のシンプルなものを回答としました)

余談になりますが、どのような方法であっても商品名と日付での検索が高速処理させるためのキーポイントとなりますので、商品名と日付でのインデックスを作成(CREATE INDEX)しておいたほうがよろしいでしょう

(1)MySQL

SELECT *
FROM Q1293380537 a
WHERE (
    SELECT `価格`
    FROM Q1293380537 b
    WHERE (b.商品名 = a.商品名) AND (b.日付 BETWEEN adddate(a.日付, INTERVAL -2 DAY) AND adddate(a.日付, INTERVAL -1 DAY))
    ORDER BY b.日付 DESC
    LIMIT 0, 1
) > a.価格
;

(2)PostgreSQL

SELECT *
FROM Q1293380537 a
WHERE (
    SELECT "価格"
    FROM Q1293380537 b
    WHERE (b.商品名 = a.商品名) AND (b.日付 BETWEEN (a.日付 - INTERVAL '2 DAYS') AND (a.日付 - INTERVAL '1 DAY'))
    ORDER BY b.日付 DESC
    LIMIT 1
) > a.価格
;

上記いずれの結果も下記(順不同)になります

日付 商品名 価格
2010-11-13 商品B 400
2010-11-14 商品A 800
2010-11-14 商品B 300

 

【2】

求めるものが上記ではなく特定の日付だけを対象とする場合はa.価格だけでなく日付の指定を追加します

(1)MySQL、PostgreSQL共通の追加項目

) > a.価格 AND (a.日付 = '2010-11-14')

結果は下記になります

日付 商品名 価格
2010-11-14 商品A 800
2010-11-14 商品B 300

 

【3】

特定の日付が当日であるならば下記のようになりますがシステムのほうで日付を入力させて【2】のようなSQLを生成するほうが扱いやすい場合が多いです

(1)MySQL

) > a.価格 AND (a.日付 = current_date())

(2)PostgreSQL

) > a.価格 AND (a.日付 = current_date)

結果は下記になります

日付 商品名 価格

(質問文のサンプルに12月のデータが無いので何も返ってきませんね)

 

これだけ書いてAccessでしたなどと言われたらまた手直しです(笑)

次回からでも結構ですから何を使っているのかを書くようにしていただきたく思います

id:kamesann

長文、ご丁寧な回答ありがとうございます。

SQLiteなので日付形式がありませんが、その部分は修正して試してみます。

年明けになってしまいますが、結果ご報告させていただこうと思います。

2010/12/31 13:16:35
id:frkw2004 No.2

ふるるP回答回数192ベストアンサー獲得回数212010/12/27 16:57:49

ポイント35pt

「二日以内に値下げした」を前日の価格より値下げしている、または二日前より値下げしている、と解釈すれば、以下のようにかけるかと。

SELECT t1.商品名, t1.日付,t1.価格, t2.日付, t2.価格, t3.日付, t3.価格,

t1.価格-t2.価格 as 価格差1, t1.価格-t3.価格 as 価格差2

from ( tblKakaku t1

Left Join tblKakaku t2

On t1.商品名=t2.商品名 and t1.日付=(t2.日付+1) )

Left Join tblKakaku t3

On t1.商品名=t3.商品名 and t1.日付=(t3.日付+2)

Where (t1.価格-t2.価格<0 and t2.価格 is not null)

or (t1.価格-t3.価格<0 and t3.価格 is not null )

ここでテーブル名をtblKakakuとして、t1,t2,t3は本日、前日、前々日、のレコードになります。

日付の加算で+1で済ませていますが、データベースによっては不可なので、それはあわせてください。また必要のない項目は削除してください。

id:kamesann

ご回答ありがとうございます。こちらも試させていただきます。

2010/12/31 13:18:17
  • id:staki
    価格が下がった後に値上がりしたケースの考慮は必要ですか?

    SqlServer ならこんなんで出そうですがいま環境が無いのでコメントにしておきます。

    -- 各日付の値下げ幅を計算して選択する場合

    SELECT DISTINCT
    MAIN.商品
    FROM
    テーブル名 AS MAIN
    INNER JOIN
    テーブル名 AS 昨日
    ON
    昨日.日付 = DateAdd('d', -1, MAIN.日付)
    AND 昨日.商品名 = MAIN.商品名
    WHERE
    昨日.価格 > MAIN.価格
    AND 2 >= DateDiff('d', 昨日.日付, MAIN.日付)
  • id:staki
    'd'の引用符はいらなかったです…。
    ほかにもなにかあるかも…。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません