質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

4回答

2382閲覧

Oracle12 SQL group byしてcountした結果に0件の結果も含めたい

rx5rra

総合スコア27

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2017/08/21 10:29

お世話になっております。
Oracle12を使用して、表題のことを実現したいのですが、group byは0件を集計しないので、困っております。
月の表を作りJOINすると言うのも考えましたが、月をずらっと並べただけの表はなんだか不自然に感じています。

sql

1 2select to_char(tl.DATE, 'YYYY/MM') month, count(NUM) as 合計数 3from テーブル tl 4where to_char(tl.DATE, 'YYYY/MM') > to_char(ADD_MONTH(SYSDATE, -6), 'YYYY/MM') 5group by to_char(tl.DATE, 'YYYY/MM') month 6order by month 7

この様なイメージの表を

NUM │ DATE │ xxxx ... ───────────── 1 │2017/03│ xxx 2 │2017/05│ xxx 3 │2017/06│ xxx 4 │2017/06│ xxx 5 │2017/06│ xxx ...

こう集計したいです。

month │ 合計数 ─────────── 2017/03 │ 1 2017/04 │ 0 ← この様に0件の行も取得したい。 2017/05 │ 1 2017/06 │ 9

この場合、どのような方法が考えられますでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

Oracleならrownumを利用することで、必ずレコード分の昇順の数値が得られるので、
下記のような方法で、カレンダー部分を生成してはいかがでしょうか?

SELECT TO_CHAR(ADD_MONTHS(SYSDATE, - rnum), 'YYYY/MM') month FROM ( SELECT rownum rnum FROM all_catalog -- 6行以上あるはずのテーブル WHERE rownum <= 6 ) ORDER BY month

あとは、上記を@SVC34 の通りWITH句に入れてしまえばいかと。
※6行以上あるはずのテーブル部分に不確定要素が含まれるのがいやらしいかもしれませんが
all_catalog システムビューは通常は6行は余裕で超えるかと。。。

投稿2017/08/22 00:10

kitaji0306

総合スコア176

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rx5rra

2017/08/22 08:19

ありがとうございます。 最初、all_catalogがわかりませんでしたが、oracleDBの管理テーブルの様なものなのですね。 これならoracleならほぼ必ず存在して、行数もまず大丈夫そうですね! ただ、LEVEL疑似列と比べるとレスポンスが少々悪い?らしいのでもう少し調べてみたいと思います。
kitaji0306

2017/08/22 08:36

そうですね、システムビューとはいえ、内部で表を参照してしまうよりは LEVEL疑似列の方がパフォーマンスはいいと思います。 (再帰クエリとしての用途でしかCONNECT BYを知らなかったのですが、LEVEL疑似列の方法なら実票を参照しないので早いと思います。)
guest

0

共通表式を使ってみてはいかがでしょうか。

sql

1WITH cal ( 2 mon 3) 4AS ( 5 SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -5), 'YYYY/MM') FROM DUAL UNION ALL 6 SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -4), 'YYYY/MM') FROM DUAL UNION ALL 7 SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -3), 'YYYY/MM') FROM DUAL UNION ALL 8 SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -2), 'YYYY/MM') FROM DUAL UNION ALL 9 SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'YYYY/MM') FROM DUAL UNION ALL 10 SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -0), 'YYYY/MM') FROM DUAL 11) 12SELECT 13 cal.mon 14 ,COUNT(num) AS 合計 15FROM 16 cal 17 LEFT OUTER JOIN テーブル tl 18 ON cal.mon = TO_CHAR(tl.date, 'YYYY/MM') 19GROUP BY 20 cal.mon 21ORDER BY 22 cal.mon 23;

再帰を使って記述することもできます。

sql

1WITH cal ( 2 ctr 3 ,mon 4) 5AS( 6 SELECT 7 1 AS ctr 8 ,TO_CHAR(SYSDATE, 'YYYY/MM') 9 FROM 10 DUAL 11 UNION ALL 12 SELECT 13 cal.ctr + 1 AS ctr 14 ,TO_CHAR(ADD_MONTHS(SYSDATE, -ctr), 'YYYY/MM') 15 FROM 16 cal 17 WHERE 18 cal.ctr <= 5 19) 20SELECT 21 cal.mon 22 ,COUNT(num) AS 合計 23FROM 24 cal 25 LEFT OUTER JOIN テーブル tl 26 ON cal.mon = TO_CHAR(tl.date, 'YYYY/MM') 27GROUP BY 28 cal.mon 29ORDER BY 30 cal.mon 31;

投稿2017/08/21 23:25

編集2017/08/22 00:03
SVC34

総合スコア1149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rx5rra

2017/08/22 08:21

ありがとうございます。 全文サンプル大変参考になります。 仮想的な表を使う際はwith句を使ったほうが良さそうですね。 調べて使ってみたいと思います
guest

0

ベストアンサー

6ヶ月分の空の表か擬似的な表をjoinすればいいじゃないですか?
雰囲気はこんな感じでしょうか。

投稿2017/08/21 13:37

szk.

総合スコア1400

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rx5rra

2017/08/22 07:55

ありがとうございます。 LEVEL擬似列は初めて聞きました。 条件を指定していない木構造のレベルを取得すると、ほぼリスト状になっているので連番になるということなのですか。 試してみたいと思います。
guest

0

月をずらっと並べただけの表はなんだか不自然に感じています。

そんなことないですよ、カレンダーテーブルは普通の仕様です
oracleの細かい仕様は理解していませんがプロシージャのような
仕組みで半自動化することもできると思います

投稿2017/08/21 10:59

yambejp

総合スコア114806

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rx5rra

2017/08/22 07:48

ありがとうございます。 カレンダーテーブルは一般的なのですね。 管理するテーブルが増えるのが違和感でしたが、調べてみたいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問