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

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

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

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

Q&A

2回答

486閲覧

連続するシフトデータをカウントしたい

amamiya_nanashi

総合スコア0

MySQL

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

0グッド

2クリップ

投稿2021/09/02 07:25

前提・実現したいこと

mysql 5.7の環境です

staff_iddatetimestatus
1012021-01-01 10:00:001
1012021-01-01 11:00:001
1012021-01-01 12:00:000
1012021-01-01 13:00:001
1012021-01-01 14:00:000
1012021-01-01 15:00:001
1012021-01-01 16:00:001
2012021-01-01 10:00:000
2012021-01-01 11:00:000
2012021-01-01 12:00:001
2012021-01-01 13:00:001
2012021-01-01 14:00:001
2012021-01-01 15:00:000
2012021-01-01 16:00:000

上記のようなシフトデータが存在した場合、
staff_id毎に、statusが1の『最小となる時間』と『1時間毎に連続する数』を取得するにはどのようにしたら良いでしょうか?

結果イメージ

最終的には以下のような結果を取得したいです

staff_idmin_datetimecount
1012021-01-01 10:00:002
1012021-01-01 13:00:001
1012021-01-01 15:00:002
2012021-01-01 12:00:003

row_numberやoverを使えれば実現出来そうだったのですが
mysql8の環境にすることは叶わない為、5.7系で代替となるSQLを書く事が出来ずに困っております
お力添え頂けますと幸いです

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

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

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

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

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

guest

回答2

0

row_numberやoverを使えれば実現出来そうだったのですが
mysql8の環境にすることは叶わない為、
5.7系で代替となるSQLを書く事が出来ずに困っております

|row_number関数は、レコードを一意に特定できる項目の組み合わせがテーブル内に存在すれば
( 今回のケースですとstaff_id + datetime )
スカラサブクエリ自己結合による集計 で模倣できます。

これらの方法は、RDBMSの種別やMySQLのバージョンに依存しないテクニックになりますから
この機会に習得しておかれることをお薦めします。

ただし、どちらの方法も
演算量が多くDBへの負荷も高い処理であることも事実ですから
日付単位でデータのカウントを区切るとか
|datetimeフィールドに抽出条件を記述して範囲を限定するなどの
チューニング無しでは、実用に耐えない可能性があるでしょう。

なお、対象とするdatetimeフィールドの範囲が広く
結果セットの行数が巨大になるのでしたら、takanaweb5さんの記述を用いればいいでしょう。

SQL

1SELECT staff_id 2 , min( ts ) min_datetime 3 , count(1) _count 4FROM 5( 6 SELECT x.staff_id 7 , x.datetime ts 8 , count(1) i 9 FROM テーブル名 x 10 , テーブル名 y 11 WHERE x.status = 1 12 AND y.status = 1 13 AND x.staff_id = y.staff_id 14 AND x.datetime >= y.datetime 15 GROUP BY 16 1, 2 17) q 18GROUP BY staff_id 19 , date_sub( ts, interval i hour ) 20ORDER BY 1, 2 21;

投稿2021/09/04 10:14

mayu-

総合スコア335

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

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

0

SQL

1SELECT T.* 2, @grp := CASE WHEN datetime = ADDTIME(@old, '01:00:00') 3 THEN @grp 4 ELSE @grp + 1 5 END AS grp 6, @old := datetime 7FROM (SELECT * FROM Table1 where status = 1 ORDER BY staff_id, datetime) AS T 8 , (SELECT @grp:=0, @old:=NULL) AS X -- 変数の初期化

を実行すると

staff_iddatetimestatusgrp@old
1012021-01-01 10:00:00112021-01-01 10:00:00
1012021-01-01 11:00:00112021-01-01 11:00:00
1012021-01-01 13:00:00122021-01-01 13:00:00
1012021-01-01 15:00:00132021-01-01 15:00:00
1012021-01-01 16:00:00132021-01-01 16:00:00
2012021-01-01 12:00:00142021-01-01 12:00:00
2012021-01-01 13:00:00142021-01-01 13:00:00
2012021-01-01 14:00:00142021-01-01 14:00:00

となります

上記の結果に対して、staff_id , grp でGROUP BY して集計関数を実行すれば良いでしょう

SQL

1SELECT 2 staff_id 3, MIN(datetime) AS min_datetime 4, COUNT(*) AS count 5FROM (上記のSELECT) AS T2 6GROUP BY 7 staff_id 8, grp

http://sqlfiddle.com/#!9/2792a9/10

投稿2021/09/03 22:37

編集2021/09/03 22:49
takanaweb5

総合スコア358

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問