web-dev-qa-db-ja.com

MySQLで次の土曜日を見つける方法

トリガーとその中にストアドプロシージャがあります(SPが実行されます)。SPに入れる次の土曜日を見つける関数が必要です。

つまり、今日は水曜日(2015-7-22)です。私のトリガーが今日実行される場合、SPで、次の土曜日(2015-7-25)を見つける必要があります。

さらに、土曜日であっても、時刻が午後9時30分より早い場合でも、当日を見つける必要があります。午後9時30分を過ぎると、次の土曜日に戻る必要があります。

ここにトリガーを全部入れてspしたいのですが、ここで混雑させたくありません。アイデアが必要です、ありがとう。

編集:

ONayeのおかげで、私はそれをコーディングしました:

CREATE DEFINER=`root`@`localhost` PROCEDURE `newGuess`(
IN `muserID` INT, 
IN `numm1` INT, 
IN `numm2` INT, 
IN `numm3` INT, 
IN `numm4` INT, 
IN `numm5` INT, 
IN `numm6` INT)
    begin
set @today = (select weekday(curdate())+1); /*monday is the first day in here*/
if @today<6 or @today=7 then /*it is NOT saturday*/
    set @nextSaturday = (SELECT DATE_ADD(NOW(),INTERVAL IF(WEEKDAY(NOW())>=5,(6-WEEKDAY(NOW())),(5-WEEKDAY(NOW()))) DAY));
end if;
if @today = 6 then /* it is saturday */
    set @current_time = (select curtime());
    set @nextSaturday = (SELECT DATE_ADD(NOW(),INTERVAL IF(WEEKDAY(NOW())>=5,(6-WEEKDAY(NOW())),(5-WEEKDAY(NOW()))) DAY));
    if @current_time < CAST('21:30:00' AS time) then
        set @nextSaturday = curdate();
    end if;
    if @current_time >=CAST('21:30:00' AS time) then
        set @nextSaturday = curdate()+INTERVAL 1 WEEK;
    end if;
end if;
insert into guessesTBL (userID,num1,num2,num3,num4,num5,num6,current__datetime,draw_date) values (muserID,numm1,numm2,numm3,numm4,numm5,numm6,NOW(),@nextSaturday);

end

今はうまくいきました。解決しました。

6
Who Cares

WEEKDAY および _DATE_ADD_ 関数を使用して、次の平日の着信を計算できます。

ここであなたがしなければならないこと:

_SELECT 
  DATE_ADD(NOW(),INTERVAL IF(WEEKDAY(NOW())>=5,
                             (6-WEEKDAY(NOW())),
                             (5-WEEKDAY(NOW()))) DAY);
_

クエリの意味:

_DATE_ADD_を使用すると、パラメーターNOW()と、土曜日の私の平日が_5_NOW()_5_以上であるかどうかを評価する必要があります。 _6_Sunday)を使用し、NOW()_5_未満_5_NOW()の曜日。

テスト:

_mysql> SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2015-07-22 07:51:33 |
+---------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_ADD(NOW(),INTERVAL IF(WEEKDAY(NOW())>=5,(6-WEEKDAY(NOW())),(5-WEEKDAY(NOW()))) DAY);
+------------------------------------------------------------------------------------------+
| DATE_ADD(NOW(),INTERVAL IF(WEEKDAY(NOW())>=5,(6-WEEKDAY(NOW())),(5-WEEKDAY(NOW()))) DAY) |
+------------------------------------------------------------------------------------------+
| 2015-07-25 07:51:34                                                                      |
+------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> 
_

編集:

実際の土曜日が午後9時30分である場合、次の土曜日を計算する必要がある場合:

新しい構文:

_SET @ACTUAL_DATE=NOW();
SET @NEXT_SATURDAY=DATE_ADD(@ACTUAL_DATE,INTERVAL IF(WEEKDAY(@ACTUAL_DATE)=5 && TIME(@ACTUAL_DATE)>'21:30:00',
                                            7,
                                            IF(WEEKDAY(@ACTUAL_DATE)>=5,
                                                (6-WEEKDAY(@ACTUAL_DATE)),
                                                (5-WEEKDAY(@ACTUAL_DATE)))) 
                                        DAY);
_

今日のテスト:

_mysql> SET @ACTUAL_DATE=NOW();
Query OK, 0 rows affected (0.01 sec)

mysql> SET @NEXT_SATURDAY=DATE_ADD(@ACTUAL_DATE,INTERVAL IF(WEEKDAY(@ACTUAL_DATE)=5 && TIME(@ACTUAL_DATE)>'21:30:00',
    -> 7,
    -> IF(WEEKDAY(@ACTUAL_DATE)>=5,
    -> (6-WEEKDAY(@ACTUAL_DATE)),
    -> (5-WEEKDAY(@ACTUAL_DATE)))) 
    -> DAY);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @NEXT_SATURDAY;
+---------------------+
| @NEXT_SATURDAY      |
+---------------------+
| 2015-07-25 21:30:01 |
+---------------------+
1 row in set (0.00 sec)

mysql> 
_

しかし、_July 25th at 21:30:01_(土曜日)にいる場合:

_mysql> SET @ACTUAL_DATE='2015-07-25 21:30:01';
Query OK, 0 rows affected (0.00 sec)

mysql> SET @NEXT_SATURDAY=DATE_ADD(@ACTUAL_DATE,INTERVAL IF(WEEKDAY(@ACTUAL_DATE)=5 && TIME(@ACTUAL_DATE)>'21:30:00',
    -> 7,
    -> IF(WEEKDAY(@ACTUAL_DATE)>=5,
    -> (6-WEEKDAY(@ACTUAL_DATE)),
    -> (5-WEEKDAY(@ACTUAL_DATE)))) 
    -> DAY);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @NEXT_SATURDAY;
+---------------------+
| @NEXT_SATURDAY      |
+---------------------+
| 2015-08-01 21:30:01 |
+---------------------+
1 row in set (0.00 sec)
_
8
oNare

動作が保証されている別の式のバリエーションがあります(電源障害がない限り)

SET @now = NOW();
SET @nextsat = DATE(DATE(@now) + INTERVAL (5-WEEKDAY(@now)) DAY
    + INTERVAL 570 MINUTE
    + INTERVAL IF((HOUR(@now)*3600+MINUTE(@now)*60+SECOND(@now))>34200,
    IF(WEEKDAY(@now)=5,1,0),0) WEEK);

ご参考までに、09:30:00 AMは

  • 570分午前0時以降
  • 4200秒午前0時以降

この数式をテストしてみましょう

たった今

mysql> SET @now = NOW();
Query OK, 0 rows affected (0.00 sec)

mysql> SET @nextsat = DATE(DATE(@now) + INTERVAL (5-WEEKDAY(@now)) DAY
    ->     + INTERVAL 570 MINUTE
    ->     + INTERVAL IF((HOUR(@now)*3600+MINUTE(@now)*60+SECOND(@now))>34200,
    ->     IF(WEEKDAY(@now)=5,1,0),0) WEEK);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @now,@nextsat;
+---------------------+------------+
| @now                | @nextsat   |
+---------------------+------------+
| 2015-07-22 11:53:33 | 2015-07-25 |
+---------------------+------------+
1 row in set (0.00 sec)

mysql>

土曜日09:29:59 AM

mysql> SET @now = '2015-07-25 09:29:59';
Query OK, 0 rows affected (0.00 sec)

mysql> SET @nextsat = DATE(DATE(@now) + INTERVAL (5-WEEKDAY(@now)) DAY
    ->     + INTERVAL 570 MINUTE
    ->     + INTERVAL IF((HOUR(@now)*3600+MINUTE(@now)*60+SECOND(@now))>34200,
    ->     IF(WEEKDAY(@now)=5,1,0),0) WEEK);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @now,@nextsat;
+---------------------+------------+
| @now                | @nextsat   |
+---------------------+------------+
| 2015-07-25 09:29:59 | 2015-07-25 |
+---------------------+------------+
1 row in set (0.00 sec)

mysql>

土曜日09:30:00 AM

mysql> SET @now = '2015-07-25 09:30:00';
Query OK, 0 rows affected (0.00 sec)

mysql> SET @nextsat = DATE(DATE(@now) + INTERVAL (5-WEEKDAY(@now)) DAY
    ->     + INTERVAL 570 MINUTE
    ->     + INTERVAL IF((HOUR(@now)*3600+MINUTE(@now)*60+SECOND(@now))>34200,
    ->     IF(WEEKDAY(@now)=5,1,0),0) WEEK);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @now,@nextsat;
+---------------------+------------+
| @now                | @nextsat   |
+---------------------+------------+
| 2015-07-25 09:30:00 | 2015-07-25 |
+---------------------+------------+
1 row in set (0.00 sec)

mysql>

土曜日09:30:01 AM

mysql> SET @now = '2015-07-25 09:30:01';
Query OK, 0 rows affected (0.00 sec)

mysql> SET @nextsat = DATE(DATE(@now) + INTERVAL (5-WEEKDAY(@now)) DAY
    ->     + INTERVAL 570 MINUTE
    ->     + INTERVAL IF((HOUR(@now)*3600+MINUTE(@now)*60+SECOND(@now))>34200,
    ->     IF(WEEKDAY(@now)=5,1,0),0) WEEK);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @now,@nextsat;
+---------------------+------------+
| @now                | @nextsat   |
+---------------------+------------+
| 2015-07-25 09:30:01 | 2015-08-01 |
+---------------------+------------+
1 row in set (0.00 sec)

mysql>

試してみる !!!

4
RolandoMySQLDBA

特定の曜日の次の日付を見つけるには、このクエリを使用します。 [〜#〜] theday [〜#〜]変数に必要な曜日の値を設定します。

    SET @THEDAY = 1;
SELECT DATE_ADD(NOW(), INTERVAL if( @THEDAY > WEEKDAY(NOW()) , (@THEDAY - WEEKDAY(NOW())) ,  (7 - WEEKDAY(NOW())) + @THEDAY) DAY)

曜日インデックスは0から始まります。月曜日の場合...... 6日曜日の場合

1
yazan

私は https://stackoverflow.com/questions/43870329/what-is-the-mysql-alternative-to-oracles-next-day-function/51879395#51879395 に同様の回答を投稿しましたここで尋ねられる質問のより一般的な解決策(時間の部分を除く)。以下の解決策は、OracleのNEXT_DAY()関数と同様に、指定された翌日(日曜日、月曜日、火曜日、水曜日、木曜日、金曜日、または土曜日)に到達するのに役立ちます。

以下のソリューションは、今日と一致する次の日を探している場合、同じ日付を返します(たとえば、次の土曜日を探し、今日が土曜日である場合、今日の日付が返されます)。ここでの質問は、午前9時30分以降の特別な場合も指定します。これはより具体的であり、より多くの魔法が必要になります。その場合は、Rolandoの回答を使用するか、このソリューションを変更して時間要件を考慮することをお勧めします。

ショートバージョン:

DAYOFWEEK()を利用すると、数値を利用して、追加する日数を示す閉じた数式を作成できます。その後、DATE_ADDを使用して日付をシフトすることができます。よりクリーンな方法があるかもしれませんが、あなたはこれから機能を作ることができるはずです。

以下は、49のユースケースすべてを検証するために使用するExcelの数式です:=MOD(MOD(Next-Input, 7)+7,7)

Excelの計算をSQLに変換する方法の例:

SELECT (((1-DAYOFWEEK('2018-08-15')) % 7)+7) % 7 AS DaysToAddToGetNextSundayFromWednesday 
FROM dual; -- 4

SELECT DATE_ADD('2018-08-15', INTERVAL (((1-DAYOFWEEK('2018-08-15')) % 7)+7) % 7 DAY) AS NextSundayFromDate 
FROM dual; -- 2018-08-19   

上記を頻繁に使用する場合は、関数またはストアドプロシージャを作成することをお勧めします。

ロングバージョン:

私は何年にもわたってこの問題に何度も遭遇しました。初めて49件すべてのケースについて巨大なケースステートメントを作成しました。これにより、クエリが非常に大きくなり、クリーンにならないことがわかりました。閉ざされた式のような、よりクリーンでシンプルなソリューションが必要でした。以下は、上記の式が機能することを確認するために行った計算の詳細です。私はこれをMySQL 5.7でテストしました。MySQL8.5を使用している場合、関数が組み込まれているようです(参照: http://www.sqlines.com/mysql/how-to/next_day )。

注:Excelは、MySQLが行うような係数の負の結果を返しません。そのため、7を追加して別の係数を実行します。

DAYOFWEEK()         
Sun     1       
Mon     2       
Tues    3       
Wed     4       
Thur    5       
Fri     6       
Sat     7       

Input   Next    Expected Days to Add    Formula Result
1       1       0                       0
1       2       1                       1
1       3       2                       2
1       4       3                       3
1       5       4                       4
1       6       5                       5
1       7       6                       6
2       1       6                       6
2       2       0                       0
2       3       1                       1
2       4       2                       2
2       5       3                       3
2       6       4                       4
2       7       5                       5
3       1       5                       5
3       2       6                       6
3       3       0                       0
3       4       1                       1
3       5       2                       2
3       6       3                       3
3       7       4                       4
4       1       4                       4
4       2       5                       5
4       3       6                       6
4       4       0                       0
4       5       1                       1
4       6       2                       2
4       7       3                       3
5       1       3                       3
5       2       4                       4
5       3       5                       5
5       4       6                       6
5       5       0                       0
5       6       1                       1
5       7       2                       2
6       1       2                       2
6       2       3                       3
6       3       4                       4
6       4       5                       5
6       5       6                       6
6       6       0                       0
6       7       1                       1
7       1       1                       1
7       2       2                       2
7       3       3                       3
7       4       4                       4
7       5       5                       5
7       6       6                       6
7       7       0                       0
1
VenomFangs