曜日と時間を唯一の情報として使用して、一連の日付を取得する必要があります。
この操作の逆、つまり WEEKDAY(date) または DAYOFWEEK(date) を使用していることは認識していますが、これは必要なものではありません。
このようなテーブルがあり、継続的にスキャンされ、現在の日付と比較されます。
+----+---------+----------+----------+
| id | weekday | start | end |
+----+---------+----------+----------+
| 1 | 1 | 09:00:00 | 17:00:00 |
| 2 | 2 | 09:00:00 | 17:00:00 |
| 3 | 3 | 09:00:00 | 17:00:00 |
| 4 | 4 | 23:00:00 | 17:00:00 |
| 5 | 5 | 18:00:00 | 23:00:00 |
| 6 | 6 | 00:00:00 | 00:00:00 |
| 7 | 7 | 00:00:00 | 01:00:00 |
+----+---------+----------+----------+
上記は単純なバージョンです。このテーブルには数百または数千の反復があると予想されます。4 行目に見られるように、時間も深夜を超える可能性があり、それを補う必要があります。
次の結果セットを提供するクエリが必要ですが、現在の年、月、および平日の列から渡された曜日に基づいて、日付をロックするのに問題があります。
結果セットの例:
+---------------------+---------------------+
| start | end |
+---------------------+---------------------+
| 2013-06-24 09:00:00 | 2013-06-24 17:00:00 |
| 2013-06-25 09:00:00 | 2013-06-25 17:00:00 |
| 2013-06-26 09:00:00 | 2013-06-26 17:00:00 |
| 2013-06-27 23:00:00 | 2013-06-28 17:00:00 | # <---- Notice the date difference here
| 2013-06-28 18:00:00 | 2013-06-28 23:00:00 |
| 2013-06-29 00:00:00 | 2013-06-30 00:00:00 | # <---- Also here, the span is 24 hours
| 2013-06-30 00:00:00 | 2013-06-30 01:00:00 |
+---------------------+---------------------+
現在の日付のみを取得することに近づいていますが、これらの日付を後で変換する必要があるため、現在の日付だけでなく、それらすべての配列が必要です。日々。
編集:現在のコードを投稿しました:これが正しい方向に向かっているとは思いませんが
SELECT TIMESTAMP(IF (end < start,
CURRENT_DATE,
SUBDATE(CURRENT_DATE, 1)),
start) AS 'start',
TIMESTAMP(IF (end < start,
CURRENT_DATE,
SUBDATE(CURRENT_DATE, 1))
end) AS 'end',
FROM shift
そして結果:
+---------------------+---------------------+
| start | end |
+---------------------+---------------------+
| 2013-06-27 23:00:00 | 2013-06-28 17:00:00 |
| 2013-06-28 18:00:00 | 2013-06-28 23:00:00 | # Needs the rest of the dates of the week
+---------------------+---------------------+
2回目の編集
以下のコメンターの助けのおかげで、私は以下のクエリにたどり着きましたが、先に進みますが、デザインに懸念を表明する人もいるので、答えを決める前にいくつかのテストを実行します. これを実現するためのより良い方法があれば、私はそれを聞くことに本当に興味があります!
最良のポイントは、クエリの途中で月が変わるときだと思います。曜日を使用して違いを判断するのは面倒かもしれません。
クエリ:
SELECT @diff:=(CAST(weekday AS SIGNED) - (WEEKDAY(CURRENT_DATE) + 1)) as 'diff',
@date:=DATE_ADD(CURRENT_DATE, INTERVAL @diff DAY) as 'start_date',
TIMESTAMP(@date, start) AS 'start',
TIMESTAMP(IF (end <= start,
DATE_ADD(@date, INTERVAL 1 DAY),
@date),
end) AS 'end'
FROM shift
結果:
+------+------------+---------------------+---------------------+
| diff | start_date | start | end |
+------+------------+---------------------+---------------------+
| -4 | 2013-06-24 | 2013-06-24 09:00:00 | 2013-06-24 17:00:00 |
| -3 | 2013-06-25 | 2013-06-25 09:00:00 | 2013-06-25 17:00:00 |
| -2 | 2013-06-26 | 2013-06-26 09:00:00 | 2013-06-26 17:00:00 |
| -1 | 2013-06-27 | 2013-06-27 23:00:00 | 2013-06-28 17:00:00 |
| 0 | 2013-06-28 | 2013-06-28 18:00:00 | 2013-06-28 23:00:00 |
| 1 | 2013-06-29 | 2013-06-29 00:00:00 | 2013-06-30 00:00:00 |
| 2 | 2013-06-30 | 2013-06-30 00:00:00 | 2013-06-30 10:00:00 |
+------+------------+---------------------+---------------------+
3 回目の編集
月の初めと終わりにまたがる期間にわたって上記のクエリをテストし、その目的に適していることがわかりました。上記のクエリといくつかのメモを回答に移動して、誰かがこれを役に立つと思うかもしれません将来。
その点について、さまざまなコメンターからのさまざまな落とし穴や推奨事項も含めます。時間を割いて助けてくれたすべての人に感謝します.