MySQL/MariaDBで特定の曜日の前々回以降の行を効率的に取得する3つの方法
MySQL/MariaDBで特定の曜日の前々回以降のすべての行を選択する方法
方法1:サブクエリを使用した方法
この方法は、サブクエリを使用して、特定の曜日の前々回の日にちを取得し、その日以降のすべての行を選択します。
SELECT *
FROM your_table
WHERE date >= (
SELECT DATE_SUB(
(
SELECT LAST_DAY(
DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)
)
),
INTERVAL DAY(CURRENT_DATE()) - day_of_month + 1 DAY
)
FROM your_table
LIMIT 1
);
説明:
LAST_DAY(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH))
:前月の最終日を取得します。INTERVAL DAY(CURRENT_DATE()) - day_of_month + 1 DAY
:現在の月のday_of_month
から特定の曜日 (day_of_month
) を引いて 1 を加えます。これにより、特定の曜日の前々回の日にちが計算されます。DATE_SUB(..., INTERVAL ...)
:上記の式を使用して計算された日から 2 日前を取得します。LIMIT 1
:サブクエリから 1 行のみ取得します。WHERE date >= ...
:メインクエリで、date
列がサブクエリで取得した日以降のすべての行を選択します。
方法2:CASE 式を使用した方法
この方法は、CASE
式を使用して、特定の曜日かどうかを判定し、その条件に基づいて行を選択します。
SELECT *
FROM your_table
WHERE DAYOFWEEK(date) = day_of_month
AND date >= (
SELECT DATE_SUB(
(
SELECT LAST_DAY(
DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)
)
),
INTERVAL DAY(CURRENT_DATE()) - day_of_month + 1 DAY
)
);
DAYOFWEEK(date) = day_of_month
:date
列が特定の曜日 (day_of_month
) かどうかを判定します。
SELECT *
FROM your_table
WHERE date >= (
SELECT DATE_SUB(
MAX(date),
INTERVAL 2 DAY
)
FROM your_table
GROUP BY DAYOFWEEK(date)
HAVING DAYOFWEEK(MAX(date)) = day_of_month
);
GROUP BY DAYOFWEEK(date)
:曜日ごとにグループ化します。MAX(date)
:各グループ内の最大の日付を取得します。
これらの方法はいずれも、特定の曜日の前々回以降のすべての行を選択することができます。状況に応じて適切な方法を選択してください。
補足:
- 上記の例では、
day_of_month
変数に特定の曜日の数値 (1 = 日曜日、2 = 月曜日、...、7 = 土曜日) を設定する必要があります。 - 上記のクエリは、MySQL 5.7.x 以降で動作します。
方法1:サブクエリを使用した方法
-- 特定の曜日を指定 (1 = 日曜日、2 = 月曜日、...、7 = 土曜日)
SET day_of_month = 2;
SELECT *
FROM your_table
WHERE date >= (
SELECT DATE_SUB(
(
SELECT LAST_DAY(
DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)
)
),
INTERVAL DAY(CURRENT_DATE()) - day_of_month + 1 DAY
)
FROM your_table
LIMIT 1
);
SET day_of_month = 2;
:特定の曜日を 2 (月曜日) に設定します。- それ以外は、方法1の説明と同じです。
方法2:CASE 式を使用した方法
-- 特定の曜日を指定 (1 = 日曜日、2 = 月曜日、...、7 = 土曜日)
SET day_of_month = 2;
SELECT *
FROM your_table
WHERE DAYOFWEEK(date) = day_of_month
AND date >= (
SELECT DATE_SUB(
(
SELECT LAST_DAY(
DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)
)
),
INTERVAL DAY(CURRENT_DATE()) - day_of_month + 1 DAY
)
);
方法3:GROUP BY 句を使用した方法
-- 特定の曜日を指定 (1 = 日曜日、2 = 月曜日、...、7 = 土曜日)
SET day_of_month = 2;
SELECT *
FROM your_table
WHERE date >= (
SELECT DATE_SUB(
MAX(date),
INTERVAL 2 DAY
)
FROM your_table
GROUP BY DAYOFWEEK(date)
HAVING DAYOFWEEK(MAX(date)) = day_of_month
);
注意事項:
- 上記のサンプルコードは、あくまでも例です。実際の使用状況に合わせて、必要に応じて修正してください。
- データベースのスキーマやテーブル名などは、ご自身の環境に合わせて変更してください。
SELECT *
FROM your_table
WHERE date >= (
SELECT MIN(date)
FROM (
SELECT date,
LAG(date, 2) OVER (ORDER BY date) AS prev_prev_date
FROM your_table
WHERE DAYOFWEEK(date) = day_of_month
) AS subq
WHERE prev_prev_date IS NOT NULL
);
LAG(date, 2) OVER (ORDER BY date) AS prev_prev_date
:現在の行から 2 行前のdate
列の値を取得します。WHERE prev_prev_date IS NOT NULL
:prev_prev_date
列が NULL ではない行のみを選択します。これは、特定の曜日の前々回の行にのみ一致する条件です。
方法5:共通テーブル式 (CTE) を使用した方法
-- 特定の曜日を指定 (1 = 日曜日、2 = 月曜日、...、7 = 土曜日)
SET day_of_month = 2;
WITH cte AS (
SELECT date
FROM your_table
WHERE DAYOFWEEK(date) = day_of_month
ORDER BY date
)
SELECT *
FROM your_table t
WHERE date >= (
SELECT date
FROM cte
ORDER BY date
LIMIT 1
OFFSET 2
);
WITH cte AS ( ... )
:CTEを使用して、特定の曜日のすべての行を含むサブクエリを定義します。SELECT date FROM your_table WHERE DAYOFWEEK(date) = day_of_month ORDER BY date
:date
列が特定の曜日 (day_of_month
) である行をすべて選択し、日付順に並べ替えます。LIMIT 1 OFFSET 2
:CTEから 1 行のみ取得し、2 番目以降の行のみを選択します。これは、特定の曜日の前々回の行にのみ一致する条件です。
特定の曜日の前々回以降のすべての行を選択するには、様々な方法があります。
- サブクエリを使用した方法
CASE
式を使用した方法GROUP BY
句を使用した方法- ウィンドウ関数を使用した方法
- 共通テーブル式 (CTE) を使用した方法
上記の方法を参考に、ご自身の環境に合った方法を選択してください。
mysql mariadb