このようなDBのテーブルがあります。


purchase_data table:
+---------------+---------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------------+------+-----+---------------------+----------------+
| data_id | bigint(20) unsigned | | PRI | NULL | auto_increment |
| purchase_date | datetime | | MUL | 0000-00-00 00:00:00 | |
| user_id | int(10) unsigned | | MUL | 0 | |
| pay | int(10) unsigned | | | 0 | |
+---------------+---------------------+------+-----+---------------------+----------------+

MySQLで以下のようなSQL文を作成しました。

SELECT user_id, sum(pay) as total
,sum(IF(purchase_date between '20061001' and '20061101',pay, 0)) as Oct
FROM purchase_data
WHERE purchase_date >= "2006/09/01"
GROUP BY user_id
ORDER BY total DESC
limit 30;

これと同じ出力になるOracle 8.1 へのSQL文を作れなくて困っています。どなたか教えていただけないでしょうか?無事に同じ出力が出たときのヒントとなった回答にポイント差し上げます。

回答の条件
  • 1人5回まで
  • 登録:2006/12/14 00:37:40
  • 終了:2006/12/18 23:38:36

ベストアンサー

id:b-wind No.2

b-wind回答回数3344ベストアンサー獲得回数4402006/12/14 11:06:54

ポイント200pt
SELECT * FROM ( SELECT user_id, sum(pay) as total
,sum(
 decode((purchase_date between to_date('20061001','YYYYMMDD') and to_date('20061101','YYYYMMDD')),TRUE,pay, 0))
as Oct
FROM purchase_data
WHERE purchase_date >= to_date('2006/09/01','YYYY/MM/DD') 
GROUP BY user_id
ORDER BY total DESC
) AS TABLE_A
where rownum <= 30;

試せる環境に無いので、decode() の中身が自信ないです。

id:izumi-h

decode(purchase_date between to_date('20061001','YYYYMMDD') and to_date('20061101','YYYYMMDD')),TRUE, の部分がうまくいかなかったです。decodeを使うのがよさそうですが、調べてみましたけど、日付の判定をどうやってdecodeの中に入れ込んだらいいかわかりませんでした。どうしたものか・・。

2006/12/15 11:03:08

その他の回答(2件)

id:andi No.1

andi回答回数448ベストアンサー獲得回数02006/12/14 00:55:51

Oracle8.1が無いので勘になってしまいますが、どうでしょうか。

①グループ化したuser_idとその合計を集計した物sum(pay)を合計の降順に30件集計したインラインビューAを作る

②グループ化したuser_idと10月分の合計を集計したインラインビューBを作る

③AとBをuser_idで結合し合計の降順にソート

select user_id,total,Oct

from (

select *

from(

select user_id,sum(pay) as total

from purchase_data

where purchase_date >= to_date('2006/09/01','YYYY/MM/DD')

group by user_id

order by total desc

)

where rownum <= 30

) A,

(

select *

from select user_id,sum(pay) as Oct

where purchase_date between to_date('2006/10/01','YYYY/MM/DD')

and ('2006/11/01','YYYY/MM/DD')

group by user_id

) B

where A.user_id = B.user_id

order by total desc

id:izumi-h

ご回答ありがとうございます。9月以降の売上ベスト30位の方について、10月にも売上が発生しているときはうまくいきました。10月に売上がないときは、当該ユーザの出力が行われなかったのですが、どうでしょうか?

2006/12/15 10:25:54
id:b-wind No.2

b-wind回答回数3344ベストアンサー獲得回数4402006/12/14 11:06:54ここでベストアンサー

ポイント200pt
SELECT * FROM ( SELECT user_id, sum(pay) as total
,sum(
 decode((purchase_date between to_date('20061001','YYYYMMDD') and to_date('20061101','YYYYMMDD')),TRUE,pay, 0))
as Oct
FROM purchase_data
WHERE purchase_date >= to_date('2006/09/01','YYYY/MM/DD') 
GROUP BY user_id
ORDER BY total DESC
) AS TABLE_A
where rownum <= 30;

試せる環境に無いので、decode() の中身が自信ないです。

id:izumi-h

decode(purchase_date between to_date('20061001','YYYYMMDD') and to_date('20061101','YYYYMMDD')),TRUE, の部分がうまくいかなかったです。decodeを使うのがよさそうですが、調べてみましたけど、日付の判定をどうやってdecodeの中に入れ込んだらいいかわかりませんでした。どうしたものか・・。

2006/12/15 11:03:08
id:andi No.3

andi回答回数448ベストアンサー獲得回数02006/12/16 02:22:31

ポイント200pt

私のSQLの一部を外部結合にして解決できませんでしょうか?駄目でしたらすみません。

where A.user_id = B.user_id

where A.user_id(+) = B.user_id

>> b-windさんのSQL

OracleのSQLにはbooleanが無い為、TRUEと言う値は使用できません。多分。

decode((purchase_date between to_date('20061001','YYYYMMDD') and to_date('20061101','YYYYMMDD')),TRUE,pay, 0))

decode(to_char(purchase_date,'YYYYMM'),'200610',pay,0)

こうしたらいけるかもです。

id:izumi-h

外部結合のほうは少し試してみましたがうまくいきませんでした。(原因を調べてないです。)

それでto_char(purchase_date,'YYYYMM'),'200610'のほうで無事に同様の出力を得ることができました。どうもありがとうございました。これにて回答の受付は一時停止扱いにして、晩にポイントの処理をします。よろしくお願いいたします。

2006/12/18 11:45:59

コメントはまだありません

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

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

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

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