人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

postgresqlについて教えてください。

下記のようなデータがあります。

年月日,売上,税込
------------------
20120101,100,105
20120115,200,210
20120305,300,315
20120603,200,210
20120801,50,52
20121201,100,105
20130101,100,105

下記のような2012年の月別の売上集計を行いたいと思っております
ポイントとしては、売上が存在しない月も出力する。
また、税抜と税込を列ではなく、行を分けて出力する。

年月,売上の集計
------------------
201201,300
201201,315
201202,0
201202,0
201203,300
201203,315
201204,0
201204,0
201205,0
201205,0
201206,200
201206,210
201207,0
201207,0
201208,50
201208,52
201209,0
201209,0
201210,0
201210,0
201211,0
201211,0
201212,100
201212,105

どのように記述すればいいのでしょうか?

●質問者: sunsunpapa
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● y-kawaz
●100ポイント ベストアンサー

その出力を必要とするシーンにツッコミたくなりますがそこはスルーしてSQLクイズのつもりで答えます。また、カラムの型とかも不明なので日付関連はdate型として話を進めます。

とりあえずテストデータを作って…

create TABLE t ("年月日" date,"売上" int,"税込" int);
INSERT INTO t VALUES('2012-01-01',100,105);
INSERT INTO t VALUES('2012-01-15',200,210);
INSERT INTO t VALUES('2012-03-05',300,315);
INSERT INTO t VALUES('2012-06-03',200,210);
INSERT INTO t VALUES('2012-08-01',50,52);
INSERT INTO t VALUES('2012-12-01',100,105);
INSERT INTO t VALUES('2013-01-01',100,105);

SQLと出力はこんな感じでどうでしょう。

 SELECT
 s.ym "年月",
 COALESCE(sum("売上"), 0) "売上の集計",
 '売上' "売上or税込"
 FROM
 (SELECT ('2012-' || s.m || '-01')::date ym FROM generate_series(1,12) as s(m)) s
 LEFT OUTER JOIN
 (SELECT date_trunc('month', "年月日") ym, "売上" FROM t) t2
 ON s.ym=t2.ym
 GROUP BY s.ym
UNION
 SELECT
 s.ym "年月",
 COALESCE(sum("税込"), 0) "売上の集計",
 '税込' "売上or税込"
 FROM
 (SELECT ('2012-' || s.m || '-01')::date ym FROM generate_series(1,12) as s(m)) s
 LEFT OUTER JOIN
 (SELECT date_trunc('month', "年月日") ym, "税込" FROM t) t2
 ON s.ym=t2.ym
 GROUP BY s.ym
ORDER BY "年月", "売上or税込";

出力

 年月 | 売上の集計 | 売上or税込
------------+------------+------------
 2012-01-01 | 300 | 売上
 2012-01-01 | 315 | 税込
 2012-02-01 | 0 | 売上
 2012-02-01 | 0 | 税込
 2012-03-01 | 300 | 売上
 2012-03-01 | 315 | 税込
 2012-04-01 | 0 | 売上
 2012-04-01 | 0 | 税込
 2012-05-01 | 0 | 売上
 2012-05-01 | 0 | 税込
 2012-06-01 | 200 | 売上
 2012-06-01 | 210 | 税込
 2012-07-01 | 0 | 売上
 2012-07-01 | 0 | 税込
 2012-08-01 | 50 | 売上
 2012-08-01 | 52 | 税込
 2012-09-01 | 0 | 売上
 2012-09-01 | 0 | 税込
 2012-10-01 | 0 | 売上
 2012-10-01 | 0 | 税込
 2012-11-01 | 0 | 売上
 2012-11-01 | 0 | 税込
 2012-12-01 | 100 | 売上
 2012-12-01 | 105 | 税込


うぃんどさんのコメント
横からごめんですが、 もう1つの質問を見るとsubstr(年月日,1,6)という記述があるので、 日付はテキストのように思います。

y-kawazさんのコメント
あ、気づきませんでした。 一応文字列版を別回答に書いておきます。

sunsunpapaさんのコメント
generate_series 便利な関数ですね。参考にさせていただきます。ありがとうございました。

2 ● y-kawaz
●100ポイント

もう一つの質問見ると年月日はテキスト型のようなので、文字列バージョンも回答しておきます。

まずテストデータを作ります。

CREATE TABLE t ("年月日" text, "売上" int, "税込" int);
INSERT INTO t VALUES('20120101',100,105);
INSERT INTO t VALUES('20120115',200,210);
INSERT INTO t VALUES('20120305',300,315);
INSERT INTO t VALUES('20120603',200,210);
INSERT INTO t VALUES('20120801',50,52);
INSERT INTO t VALUES('20121201',100,105);
INSERT INTO t VALUES('20130101',100,105);

SQLです。

 SELECT
 s.ym "年月",
 COALESCE(sum("売上"), 0) "売上の集計",
 '売上' "売上or税込"
 FROM
 (SELECT ym::text FROM generate_series(201201,201212) as s(ym)) s
 LEFT OUTER JOIN
 (SELECT substr("年月日",1,6) ym, "売上" FROM t) t2
 ON s.ym=t2.ym
 GROUP BY s.ym
UNION
 SELECT
 s.ym "年月",
 COALESCE(sum("税込"), 0) "売上の集計",
 '税込' "売上or税込"
 FROM
 (SELECT ym::text FROM generate_series(201201,201212) as s(ym)) s
 LEFT OUTER JOIN
 (SELECT substr("年月日",1,6) ym, "税込" FROM t) t2
 ON s.ym=t2.ym
 GROUP BY s.ym
ORDER BY "年月", "売上or税込";

出力です。

 年月 | 売上の集計 | 売上or税込
--------+------------+------------
 201201 | 300 | 売上
 201201 | 315 | 税込
 201202 | 0 | 売上
 201202 | 0 | 税込
 201203 | 300 | 売上
 201203 | 315 | 税込
 201204 | 0 | 売上
 201204 | 0 | 税込
 201205 | 0 | 売上
 201205 | 0 | 税込
 201206 | 200 | 売上
 201206 | 210 | 税込
 201207 | 0 | 売上
 201207 | 0 | 税込
 201208 | 50 | 売上
 201208 | 52 | 税込
 201209 | 0 | 売上
 201209 | 0 | 税込
 201210 | 0 | 売上
 201210 | 0 | 税込
 201211 | 0 | 売上
 201211 | 0 | 税込
 201212 | 100 | 売上
 201212 | 105 | 税込
(24 行)

基本は全く変えてません、日付操作を文字列操作にしただけです。

関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ