MySQL

1ラインでプレミアムフライデーを求めてみた

とある業務システムでプレミアムフライデーに自動で割引を付けたいとのことで
今更ながらプレミアムフライデーを求める式を考えてみた。

巷によくあるのは、ループでぐるぐるするタイプが多い。
ソース読んでわかりやすいし、あとあとメンテも楽だろうけど
でもそれだと、SQLやEXCELでわざわざストアドやマクロ書かないといけなくてちょっと使いにくい。

曜日はプログラムでは数値で表される、7進数だと考えると
カレンダーは曜日を表すとこんな感じに並べられている。

   3 4 5 6
0 1 2 3 4 5 6
0 1 2 3 4 5 6
0 1 2 3 4 5 6
0 1 2 3 4

そこでこんな式を考えた。

月末日 - 7 + (目標曜日 - 月末の曜日)

もし金曜日をあらわすのが 5 だったら
5 - 月末の曜日(4) = 1
なので、月末 マイナス 7日 + 1すればいい

しかし、別の世界線ではプレミアムウェンズデーかもしれない
その場合、水曜日を表すのが 3 だとすれば?

3 - 月末の曜日(4) = -1

この場合月末に マイナス7 すると 月末 - 8となって最終水曜日ではなくなり、おかしなことになる。

ピコーン
じゃあ、剰余 使ってみるか!

月末日 + ((目標曜日 - 月末の曜日 - 7) MOD 7)

mysql> SELECT DATE_ADD(LAST_DAY(CURRENT_DATE()), INTERVAL MOD(4 - WEEKDAY(LAST_DAY(CURRENT_DATE())) - 7, 7) DAY);
+----------------------------------------------------------------------------------------------------+
| DATE_ADD(LAST_DAY(CURRENT_DATE()), INTERVAL MOD(4 - WEEKDAY(LAST_DAY(CURRENT_DATE())) - 7, 7) DAY) |
+----------------------------------------------------------------------------------------------------+
| 2017-11-24                                                                                         |
+----------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

おおお!行けてるっぽいぞ!

【追記】
この式は負の剰余を使うため、PerlやPythonなど一部言語では使用できないとのこと。