2009-02-28 1 views
1

特定の月に挿入されたすべての行を取得しようとしています。T-Sqlを使用して、指定された月に挿入されたすべての行を取り出す方法

SELECT 
    dbo.Post.UserId, 
    dbo.Post.Tags, 
    dbo.Post.CommentCount, 
    dbo.Post.Status, 
    dbo.Post.PostDate, 
    dbo.Post.[Content], 
    dbo.Post.Title, 
    dbo.Post.PostId, 
    dbo.[User].DisplayName 
FROM 
    dbo.Post INNER JOIN 
    dbo.[User] ON dbo.Post.UserId = dbo.[User].UserId 
Where PostDate >= DATEADD(mm, 0, DATEDIFF(mm, 0, '01/28/2009')) 
    AND PostDate <= DATEADD(mm, 0, DATEDIFF(mm, 0, '01/28/2009')) 

アイデアはありますか?

答えて

2
WHERE PostDate >= DATEADD(mm, DATEDIFF(mm, 0, '01/28/2009'), 0) 
    AND PostDate < DATEADD(mm, 1 + DATEDIFF(mm, 0, '01/28/2009'), 0) 
+0

私はこの1つ1 – dotjoe

0
@dtInput = '01/28/2009' 

-- subtract current days (less one) to get to start of month 
set @dtStart = dateadd(dd, 1 - datepart(dd, @dtInput), @dtInput) 

-- add a month, then subtract 1 sec to get 23:59:59 on last day of month 
set @dtEnd = dateadd(ss, -1, dateadd(mm, 1, @dtStart)) 

SELECT ... WHERE PostDate between @dtStart and @dtEnd 
+0

あなたのクエリをテストを見ていない、括弧の –

1

あなたは始めた瞬間を含むとから日付を取ると、次の開始の瞬間を含めまでではなく、その後、その月の開始時点と次の月の開始の瞬間を作成したいです。

I.e.結果は次のものと同等である必要があります。

これで、正確にその月が得られ、次の月に重複することはありません。

表現DATEDIFF(mm, 0, '2009-01-28')あなたはDATEADDで三番目のパラメータとしてその日付を使用する必要がありますので、01/01/1900からあなたの月数を与える:

DATEADD(mm, DATEDIFF(mm, 0, '01/28/2009'), '01/01/1900') 

をあなただけの使用来月の開始時点を取得するにはオフセットとして'02/01/1900'。条件でこれを入れてみましょう:

Where 
    PostDate >= DATEADD(mm, DATEDIFF(mm, 0, '01/28/2009'), '01/01/1900') and 
    PostDate < DATEADD(mm, DATEDIFF(mm, 0, '01/28/2009'), '02/01/1900') 
+0

IMOあなたはdataaddで第三引数として0を使うべきで間違いがあります。これは、datadiffの2番目のパラメータと一致する必要があります。次に、'02/01/1900 'を使用する代わりに、datadiffの結果に1を加えます。 – dotjoe

+0

さらに、両方の場所で実際の日付を使用してください。次に、'01/01/2000 'のような神秘的なゼロの日付よりも良い日付を使用することができます。それは両方の場所で同じである限り、本当に何日かは問題ではありません。 – Guffa

+0

文字列は実際の日付ではありません... '2/1/2009'はjanです。 2nd!?!ゼロは常に基準日となります。キャスト(datetimeとして0)何も神秘的ではありません。 – dotjoe

3

あなたが日付で開始し、ちょうどその月内にあるすべてのものをしたい場合は、私は1から12までの月数を仮定している、「与えられた月」のために言及:

@month = datepart(mm, 'given date'); 
@year = datepart(yy, 'given date'); 

Then use: 

Where 
    datepart(mm, Post.Postdate) = @month 
    and datepart(yy, Post.PostDate) = @year 

そうです。

(私はあなたがそれを気にする場合には年を追加。:-))

+0

これは、年を気にしない場合に便利です –

+0

これはデータ量が少ない限りは問題ありませんが、常にテーブルスキャンなのでボリュームが上がるにつれて遅くなります。他のソリューションでは、日付列のインデックスを利用することができます。ボリュームが高く、インデックスがクラスタ化されている場合は非常に多くなります。 –

+0

@年が世話をします。このクエリは、証明書の年/月があなたが探しているものであることを示します。日付範囲が必ずしもそれを教えてくれるわけではありません。しかし、私はコメントがそうだと確信している;) – JeffO

1

これはそれを行います。

Where PostDate >= DATEADD(mm, DATEDIFF(mm, 0, '01/28/2009'), 0) 
    AND PostDate < DATEADD(mm, DATEDIFF(mm, 0, '01/28/2009') + 1, 0) 

また、私は通常、クエリの前に日付範囲を設定していますので、where句に日付関数を入れる必要はありません。

declare @from datetime; 
declare @thru datetime; 

set @from = DATEADD(mm, DATEDIFF(mm, 0, '01/28/2009'), 0); 
set @thru = DATEADD(mm, 1, @from); 

... 
Where PostDate >= @from 
     AND PostDate < @thru 
関連する問題