プロが教えるわが家の防犯対策術!

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';

A 回答 (4件)

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です。
    • good
    • 0

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は、それ程、多くないので注意しましょう。
    • good
    • 0

 このtrunc()を使用してグルーピングする例の表すところは、group byの指定には、意味のある値を返す関数なら、何でも指定できると言うことです。


 つまり、ユーザー関数でもかまいません。create functionで、一つのdateを与えられたら、年度を返す関数を作ってしまえば、それを使えばよいと言うことです。
 この手を利用すれば、どんな場合でも、ちゃんとグループする規則を作れさえすればgroup byが使用できます。ちなみに、関数の引数は単独である必要さえありません。複数のフィールドの相関関係が関わる複雑な条件でもOKです。ただし、同じ引数を与えたら、常に同じ結果を返す関数である必要があります。これは、関数が状態を持ってはいけないと言うことです。例えば、前回呼ばれた値を利用して今回の結果を作るとか、他のテーブルに関数内でアクセスして結果を作るとかいう関数は使えませんのでご注意ください。
    • good
    • 0

年月の部分でグループ化します。

date_trunc関数を使います。

select sum(a),sum(b) from uriage
group by date_trunc('month',date)

http://www.postgresql.jp/document/pg734doc/user/ …
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
カラムの値に手を加えてグループ化とは全く思いつきませんでした。大変勉強になりました。

もしまたここをご覧になっていたらお教えください。
今回の質問は1ヶ月単位の売上げ集計でアドバイスのおかげで実現できました(ありがとうございます)
ところで、今後1年間の集計がしたいとなった場合できるのかという疑問がわきました。
仕事の1年間なので普通の1/1始まりではなく、4/1~3/31という1年間なのでグルーピングが不可能となり、SQL1つで年間売上高を出すのは不可能だろうと思ったのですがどうでしょうか?

お礼日時:2008/11/11 17:51

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!