特定の月のすべてのレコードを検索するWHERE句


83

ストアドプロシージャに月と年を指定して、その月に発生するすべてのものを返すようにしたいのですが、月によって日数が異なるなどの理由で比較できないため、これを行うにはどうすればよいですか?

これを行うための最良の方法は何ですか?年と月に基づいて比較するように依頼できますか?

ありがとう。

回答:


181

あなたが探している機能はですMONTH(date)。おそらく「YEAR」も使用することをお勧めします 。

things次のような名前のテーブルがあるとしましょう。

id happend_at
-- ----------------
1  2009-01-01 12:08
2  2009-02-01 12:00
3  2009-01-12 09:40
4  2009-01-29 17:55

そして、happened_at2009/01月(2009年1月)の間にあるすべてのレコードを検索するために実行するとします。SQLクエリは次のようになります。

SELECT id FROM things 
   WHERE MONTH(happened_at) = 1 AND YEAR(happened_at) = 2009

どちらが返されますか:

id
---
1
3
4

13
確かに !「DAY、MONTH、およびYEAR関数は、それぞれDATEPART(dd、date)、DATEPART(mm、date)、およびDATEPART(yy、date)の同義語です。」に興味がある人のために。
Tarks 2009年

15

ほとんどの応答で提案されているようにMONTH関数とYEAR関数を使用すると、SQLServerが日付列にある可能性のあるインデックスを使用できないという欠点があります。これにより、大きなテーブルのパフォーマンスが低下する可能性があります。

関心のある月の最初の日を表すストアドプロシージャにDATETIME値(@StartDateなど)を渡す傾向があります。

その後、使用することができます

SELECT ... FROM ...
WHERE DateColumn >= @StartDate 
AND DateColumn < DATEADD(month, 1, @StartDate)

月と年を個別のパラメーターとしてストアード・プロシージャーに渡す必要がある場合は、CASTとCONVERTを使用して月の最初の日を表すDATETIMEを生成してから、上記のように続行できます。これを行う場合は、整数の年、月、日の値からDATETIMEを生成する関数を作成することをお勧めします。たとえば、SQLServerブログの次のようになります

create function Date(@Year int, @Month int, @Day int)
returns datetime
as
    begin
    return dateadd(month,((@Year-1900)*12)+@Month-1,@Day-1)
    end
go

クエリは次のようになります。

SELECT ... FROM ...
WHERE DateColumn >= Date(@Year,@Month,1)
AND DateColumn < DATEADD(month, 1, Date(@Year,@Month,1))

1
Ya私は@joeに同意します。「ほとんどの応答で提案されているようにMONTH関数とYEAR関数を使用すると、SQLServerが日付列にあるインデックスを使用できないという欠点があります。これにより大きなテーブルのパフォーマンスが低下する可能性があります。 。」
Raghav

何か追加してもいいですか?パラメータで '@StartDateを宣言している場合は、SQLに各行の計算を行わせるのではなく、' @ EndDateを宣言してそこにDATEADDを配置します。
dataGirl 2015年

@ DataGirl-興味深い点。DATEADD関数は実行時定数として扱われ、一度だけ評価されると想定していました。これについて疑問がある場合は、宣言@EndDateすることで明示的になります。
ジョー

3

MONTH関数とYEAR関数の代わりに、通常のWHERE句も機能します。

select *
from yourtable
where '2009-01-01' <= datecolumn and datecolumn < '2009-02-01'

3

もう1つのヒントは非常に簡単です。to_char関数を使用することもできます。

月の場合:

to_char(happened_at、 'MM')= 01

年間:
to_char(happened_at、 'YYYY')= 2009

日のために:

to_char(happened_at、 'DD')= 01

to_char関数は、特定の1つのデータベースではなく、SQL言語によってサポートされています。

もっと誰かを助けてくれるといいのですが...

腹筋!


1
これはOracleでのみ機能するという印象がありますが、これは非常に具体的です。SQLServerは間違いなくそれをサポートしていません。
キャロル


1

年と月に基づいて比較するように依頼できますか?

あなたはできる。これは、AdventureWorksサンプルデータベースを使用した簡単な例です...

DECLARE @Year       INT
DECLARE @Month      INT

SET @Year = 2002
SET @Month = 6

SELECT 
    [pch].* 
FROM 
    [Production].[ProductCostHistory]   pch
WHERE
    YEAR([pch].[ModifiedDate]) = @Year
AND MONTH([pch].[ModifiedDate]) = @Month

1

私はそれが簡単に(例えば、時間的データ型として値を渡すために見つけDATETIME、次に具体的には、一時的な機能を使用)DATEADDし、DATEPARTこの場合には、月がこの発見に開始日と終了日のペアを、たとえば、期間の開始日と終了日を見つけるために、今月CURRENT_TIMESTAMPは、タイプのパラメータに置き換えてくださいDATETIME(1990-01-01の値は完全に任意であることに注意してください)。

SELECT DATEADD(M, 
          DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
          '1990-01-01T00:00:00.000'), 
       DATEADD(M, 
          DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
          '1990-01-31T23:59:59.997')

0

このような何かがそれを行う必要があります:

select * from yourtable where datepart(month,field) = @month and datepart(year,field) = @year

または、レコードを作成するときに月と年を独自の列に分割して、それらに対して選択することもできます。

イアン


0

1つの方法は、月の最初(つまり、2009年5月1日)を表す変数を作成し、それをprocに渡すか、ビルド(月/ 1 /年を連結)することです。次に、DateDiff関数を使用します。

WHERE DateDiff(m,@Date,DateField) = 0

これにより、月と年が一致するものがすべて返されます。


-4
SELECT * FROM yourtable WHERE yourtimestampfield LIKE 'AAAA-MM%';

AAAAあなたが望む年とあなたが望むMM月はどこですか

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.