teratail header banner
teratail header banner
質問するログイン新規登録

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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

2回答

317閲覧

SQLのグループ集計でデータがないときも表示するには?

yuko0524

総合スコア28

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2023/09/15 04:27

編集2023/09/15 04:55

0

0

実現したいこと

日付の範囲指定をして、その間の1時間ごと、場所ごとの滞在時間を集計したいのですが、
その際にまたデータがない時間も0で表示したいです。
どのような記述だと実現できますでしょうか。

<出力イメージ>
日付(yyyy-mm-dd hh:00) 場所 滞在時間計
2023-09-10 01:00 場所A 10
2023-09-10 02:00 場所A 20
2023-09-10 02:00 場所B 40
2023-09-10 03:00 場所B 20
2023-09-10 04:00 0
2023-09-10 05:00 0
2023-09-10 06:00 場所B 10
2023-09-10 07:00 場所A 60
・・・
2023-09-15 23:00 場所A 50
2023-09-15 23:00 場所B 5

前提

テーブル:T_01
・日付 datehour(yyyy-mm-dd hh:mm:ss)
・場所 work(文字列)
・滞在時間 stay_time(数値)
ある処理で、n秒おきにT_01にデータを書き込んでいます。
それを時間帯、場所ごとに集計しようとしています。

該当のソースコード

SQL

1SELECT 2DATE_FORMAT(t.datehour,'%Y-%m-%d %H:00') AS 日付 3 ,t.work AS 場所 4 ,sum(t.stay_time) as 滞在時間計 5FROM 6 T_01 t 7WHERE 8 DATE_FORMAT(t.datehour,'%Y%m%d') BETWEEN '20230915' AND '20230920' 9GROUP BY 日付,場所; 10

試したこと

時間ごと&場所ごとに時間を集計するところまでは確認できています。
しかし、データがある時間だけではなく、ない時間帯のデータも出力するSQL文に苦戦してます。

補足情報(FW/ツールのバージョンなど)

MySQL 8.0.31

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

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

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

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

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

yambejp

2023/09/15 04:49

具体的に想定する結果を例示ください
yuko0524

2023/09/15 05:22

ご質問ありがとうございます。 <出力イメージ> 日付(yyyy-mm-dd hh:00) 場所 滞在時間計 2023-09-10 01:00 場所A 10 2023-09-10 02:00 場所A 20 2023-09-10 02:00 場所B 40 2023-09-10 03:00 場所B 20 2023-09-10 04:00 0 2023-09-10 05:00 0 2023-09-10 06:00 場所B 10 2023-09-10 07:00 場所A 60 ・・・(省略) 2023-09-15 23:00 場所A 50 2023-09-15 23:00 場所B 5 になります。 生データは、このような感じです。 日付(yyyy-mm-dd hh:mm:ss) ,場所, 滞在時間 2023/9/10 1:10:01,場所A,5 2023/9/10 1:21:23,場所A,5 2023/9/10 2:20:06,場所A,8 2023/9/10 2:50:34,場所A,12 2023/9/10 2:10:00,場所B,30 2023/9/10 2:43:32,場所B,10 2023/9/10 3:00:33,場所B,18 2023/9/10 3:10:00,場所B,2 2023/9/10 6:11:20,場所B,1 2023/9/10 6:30:09,場所B,1 2023/9/10 6:48:09,場所B,8 2023/9/10 7:19:19,場所A,37 2023/9/10 7:19:19,場所A,23 ・・・(省略) 2023/9/15 23:09:01,場所A,16 2023/9/15 23:25:51,場所A,11 2023/9/15 23:35:11,場所A,23 2023/9/15 23:02:11,場所B,5 4時と5時のデータがないので、そこは 04:00,05:00と表示しながらも 時間計は0で表示をしたいのが実現したいことになります。
guest

回答2

0

ベストアンサー

再帰SQLを利用してカレンダーテーブルを作成し、そのカレンダーテーブルとLEFT OUTER JOINすればよいと思います。

SQL

1WITH RECURSIVE cal(dt) AS ( 2 SELECT STR_TO_DATE('2023-09-15 00:00', '%Y-%m-%d %H:%i') 3 UNION ALL 4 SELECT DATE_ADD(dt, INTERVAL 1 HOUR) 5 FROM cal 6 WHERE dt < STR_TO_DATE('2023-09-20 23:00', '%Y-%m-%d %H:%i') 7) 8SELECT DATE_FORMAT(C.dt,'%Y-%m-%d %H:00') AS 日付, COALESCE(T.場所, 0) AS 場所, COALESCE(T.滞在時間計, 0) AS 滞在時間計 9FROM cal C 10LEFT OUTER JOIN ( 11 SELECT DATE_FORMAT(datehour,'%Y-%m-%d %H:00') AS 日付, work AS 場所, sum(stay_time) AS 滞在時間計 12 FROM T_01 13 GROUP BY 日付, 場所 14) T ON DATE_FORMAT(C.dt,'%Y-%m-%d %H:00') = T.日付

投稿2023/09/15 06:11

neko_the_shadow

総合スコア2395

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

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

yuko0524

2023/09/15 08:26

ありがとうございます。 再帰SQLでやりたいことは実現できそうです。 ただ、条件範囲が広くなったときの対策も考えたいと思います。 とはいえ、今後も活用できる方法なので、ありがたく参考にいたします。 この度はありがとうございました。助かりました。
guest

0

SELECT
(t.datehour),'%Y-%m-%d %H:00') AS 日付

とりあえず間違えています

SQL

1SELECT 2 DATE_FORMAT(t.datehour,'%Y-%m-%d %H:00') AS 日付

追記

連続データ

SQL

1SELECT (select @a := @a + interval 1 hour from (select @a:='2023-09-10 00:00') as dummy) AS num 2FROM information_schema.COLUMNS 3where @a<='2023-09-15 23:00'

を実行し連続データを発生させ、これに集計結果をleft joinしてやるとよいでしょう
※データが大量になるとデータが途中で切れる可能性があります

投稿2023/09/15 04:49

編集2023/09/15 05:30
yambejp

総合スコア117871

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

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

yuko0524

2023/09/15 04:53

ご指摘ありがとうございます。 コピペをミスりました・・・。
yambejp

2023/09/15 05:31

連続データの生成ロジックだけ追記しておきました
yuko0524

2023/09/15 08:27

ありがとうございます。仮想を使うやり方は今後に活かせそうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問