月と年のみに基づいてSQLの日付を比較する最良の方法を決定するのに苦労しています。
日付に基づいて計算を行います。請求は月単位で行われるため、月の日付がより多くの障害を引き起こしています。
例えば
DECLARE @date1 DATETIME = CAST('6/15/2014' AS DATETIME),
@date2 DATETIME = CAST('6/14/2014' AS DATETIME)
SELECT * FROM tableName WHERE @date1 <= @date2
@ date1は@ date2より大きいため、上記の例では行は返されません。だから私は方程式から一日を取る方法を見つけたいです。
同様に、次の状況でも同じ理由で悲しみを覚えます。
DECLARE @date1 DATETIME = CAST('6/14/2014' AS DATETIME),
@date2 DATETIME = CAST('6/15/2014' AS DATETIME),
@date3 DATETIME = CAST('7/1/2014' AS DATETIME)
SELECT * FROM tableName WHERE @date2 BETWEEN @date1 AND @date3
日付のインライン変換を行って、指定された日付の月の最初の日と最後の日を導き出しました。
SELECT *
FROM tableName
WHERE date2 BETWEEN
DATEADD(month, DATEDIFF(month, 0, date1), 0) -- The first day of the month for date1
AND
DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, date2) + 1, 0)) -- The lastday of the month for date3
これを行うには簡単な方法が必要です。助言がありますか?
間のような不等式を処理するために、日付/時刻を文字列または整数としてYYYYMM表現に変換するのが好きです。この例では:
DECLARE @date1 DATETIME = CAST('6/14/2014' AS DATETIME),
@date2 DATETIME = CAST('6/15/2014' AS DATETIME),
@date3 DATETIME = CAST('7/1/2014' AS DATETIME);
SELECT * FROM tableName WHERE @date2 BETWEEN @date1 AND @date3;
クエリを次のように記述します。
SELECT *
FROM tableName
WHERE year(@date2) * 100 + month(@date2) BETWEEN year(@date1) * 100 + month(@date1) AND
year(@date3) * 100 + month(@date1);
次のように、特定の日付の月と年を現在の日付にフィルターできます。
_SELECT *
FROM tableName
WHERE month(date2) = month(getdate()) and year(date2) = year(getdate())
_
GETDATE()
メソッドを目的の日付に置き換えるだけです。
最初に、使用している_'YYYYMMDD'
_ではなく、標準の_'6/15/2014'
_のような明確な日付の形式を使用します。 Aaron Bertrandのブログは、私ができるよりもはるかによく、これがうまくいかないさまざまな方法を説明しています。
悪い習慣:日付/範囲のクエリを誤って処理する
特定の問題については、月の最初と最後の日(date1とdate3)を見つける最後のクエリは、私が正しいと思う意見です。 evil BETWEEN
:を避ければ、月の最初の日(date1の最初の日とdate3の翌月の最初の日)だけが必要です。 BETWEENと悪魔の共通点は何ですか?
_SELECT *
FROM tableName
WHERE date2 >= DATEADD(month, DATEDIFF(month, '19000101', @date1), '19000101')
AND date2 < DATEADD(month, 1+DATEDIFF(month, '19000101', @date3), '19000101') ;
_
クエリは、_date2
_(DATE
、DATETIME
、_DATETIME2
_、またはSMALLDATTEIME
)のデータ型に関係なく、そのまま機能します。
ボーナスポイント、_date2
_のインデックスは、このようにオプティマイザーによって考慮されます。
(別の)Aaronのブログ投稿によると、DATEDIFF()
を使用して式を評価する際のカーディナリティ推定の問題を回避するための改善:
パフォーマンスの驚きと仮定:DATEDIFF
_SELECT *
FROM tableName
WHERE date2 >= CONVERT(DATE, DATEADD(day, 1 - DAY(@date1), @date1))
AND date2 < DATEADD(month, 1,
CONVERT(DATE, DATEADD(day, 1 - DAY(@date3), @date3))) ;
_
この 'yyyyMM'のように日付の書式設定を使用できるため、同じ年の月のみが選択されます。
SELECT *
FROM tableName
WHERE FORMAT(date_month_bill, 'yyyyMM') < FORMAT(DATEADD(MONTH, -1, GETDATE()), 'yyyyMM')
AND FORMAT(date_month_bill, 'yyyyMM') > FORMAT(DATEADD(MONTH, -3, GETDATE()), 'yyyyMM')