- 締切済み
売り上げ集計SQLが作れません
1つのTABLEに、1日の売上げ高を商品ごとに登録していくDBがあります。 簡単な構造は以下のとおりです。 日付 |A品売上額 |B品売上額 | 2008/11/01 |500000 |600000 | 2008/11/02 |450000 |800000 | 2008/11/03 |100000 |700000 | ・・・ 2008/11/30 |200000 |500000 | 2008/12/01 |300000 |100000 | <質問> それぞれの商品の1ヶ月売上高をSQLで抽出したいと思うのですが、Group byで何を指定したらいけるのかわからず困っています。 SQLで計算せずに抽出だけ行って、CGI側で計算するしかないのでしょうか? アドバイスお願いいたします。 <最初に考えたSQL(Group byがないためエラーになりました)> select sum(a),sum(b) from uriage where date between '2008/11/01' AND '2008/11/30';
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- nda23
- ベストアンサー率54% (777/1415)
3ヶ月ずらせば良いのでは? select date_part('year',date_trunc('year',date - interval '3 month')) as NENDO ,sum(a) as TOTAL_A,sum(b) as TOTAL_B from uriage group by date_trunc('year',date - interval '3 month') date_partやdate_truncはバージョンにより使用できないかも 知れません。こちらの環境は8.2です。
- chukenkenkou
- ベストアンサー率43% (833/1926)
RDBMSは、ここのカテゴリ通りPostgreSQLなのですね? 具体的なアドバイスをしても、lovesberryさんの環境では動かない可能性もあるので、バージョンも書きましょう。 1.to_char関数を使って、年月でグループ集計 select to_char(hiduke,'YYYY-MM') as yyyymm, sum(A_uri), sum(B_uri) from t1 group by yyyymm order by yyyymm 2.年度でグループ集計 select case when date_part('month',hiduke)<=3 then date_part('year',hiduke)-1 else date_part('year',hiduke) end as 年度, -- date_part('month',hiduke) as 月, sum(A_uri), sum(B_uri) from t1 group by 年度 order by 年度 なお、関数などで列を加工すると、列にインデクスが定義されていても有効利用できない場合があるので、性能を重視する場合は注意しましょう。どうしても加工が必要で、しかも性能を出したい場合は、式にインデクスを定義しましょう。ただし、式にインデクスを定義できるRDBMSは、それ程、多くないので注意しましょう。
- mitoneko
- ベストアンサー率58% (469/798)
このtrunc()を使用してグルーピングする例の表すところは、group byの指定には、意味のある値を返す関数なら、何でも指定できると言うことです。 つまり、ユーザー関数でもかまいません。create functionで、一つのdateを与えられたら、年度を返す関数を作ってしまえば、それを使えばよいと言うことです。 この手を利用すれば、どんな場合でも、ちゃんとグループする規則を作れさえすればgroup byが使用できます。ちなみに、関数の引数は単独である必要さえありません。複数のフィールドの相関関係が関わる複雑な条件でもOKです。ただし、同じ引数を与えたら、常に同じ結果を返す関数である必要があります。これは、関数が状態を持ってはいけないと言うことです。例えば、前回呼ばれた値を利用して今回の結果を作るとか、他のテーブルに関数内でアクセスして結果を作るとかいう関数は使えませんのでご注意ください。
- nda23
- ベストアンサー率54% (777/1415)
年月の部分でグループ化します。date_trunc関数を使います。 select sum(a),sum(b) from uriage group by date_trunc('month',date) http://www.postgresql.jp/document/pg734doc/user/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
お礼
回答ありがとうございます。 カラムの値に手を加えてグループ化とは全く思いつきませんでした。大変勉強になりました。 もしまたここをご覧になっていたらお教えください。 今回の質問は1ヶ月単位の売上げ集計でアドバイスのおかげで実現できました(ありがとうございます) ところで、今後1年間の集計がしたいとなった場合できるのかという疑問がわきました。 仕事の1年間なので普通の1/1始まりではなく、4/1~3/31という1年間なのでグルーピングが不可能となり、SQL1つで年間売上高を出すのは不可能だろうと思ったのですがどうでしょうか?