履歴データをクエリしようとしていますが、1か月の期間(2週間前と2週間前)のデータを返す必要がありますが、年は関係ありません。
したがって、今日クエリを実行する場合は、date
xxxx-06-31からxxxx-07-27までのすべての行が必要になります。
助けてくれてありがとう!
編集:私は2つの方法を試しました。どちらも新年を迎えることはできないと思います。1つはdatepart(day)を使用することで、もう1つは単に年を日付から外して比較することです。
この問題を考える最良の方法は、日付をその年の日に対応する0から365までの数値に変換することです。次に、この差が14未満の日付を選択するだけで、2週間のウィンドウが得られます。
それは年の初めか終わりに崩壊するでしょう。しかし、単純なモジュラー演算が答えを与えます。
幸い、MySQLにはがありますDAYOFYEAR(date)
ので、それほど複雑ではありません。
SELECT * FROM tbl t
WHERE
MOD(DAYOFYEAR(currdate) - DAYOFYEAR(t.the_date) + 365, 365) <= 14
OR MOD(DAYOFYEAR(t.the_date) - DAYOFYEAR(currdate) + 365, 365) <= 14
+ 365
MySQLのMODは負の数を返すため、この追加が必要です。
この回答はうるう年を正しく考慮していません。今年がうるう年ではなく、年末から14日以内の場合は、含めるべき1月の1日を逃します。それが気になる場合は365
、[the number of days in the year - 1
]に置き換える必要があります。
あなたがこのような日付を持っていると仮定すると、
create table datelist
(
d date
);
insert into datelist values
('2012-07-01'),
('2011-06-29'),
('2012-07-02'),
('2010-07-05'),
('2012-05-31'),
('2010-06-30');
以下のこのクエリを試してください、
SELECT d, date_format(d,'%Y-%b-%d')
FROM datelist
WHERE (MONTH(d) = 6 AND DAYOFMONTH(d) >= 30)
OR (MONTH(d) = 7 AND DAYOFMONTH(d) <= 27)
解決策がひどく遅い場合でも大丈夫ですか?
SELECT tbl.*
FROM tbl
INNER JOIN (SELECT COALESCE(DATE(CONCAT(yyyy, '-', MONTH(CURRENT_DATE), '-', DAYOFMONTH(CURRENT_DATE)),
DATE(CONCAT(yyyy, '-02-28'))) AS midpoint
FROM (SELECT DISTINCT(YEAR(d)) AS yyyy
FROM tbl) all_years) adjusted
ON tbl.datecol BETWEEN adjusted.midpoint - INTERVAL 2 WEEK
AND
adjusted.midpoint + INTERVAL 2 WEEK;
これにより、データセット内のすべての年のすべての中間点が計算され、年末のラッピングを処理するそのような中間点から±2週間でレコードが取得されます。
COALESCEは、飛躍のない年に02-29を処理し(MySQLはこれをNULL化します)、02-28に強制します。