2009-07-11 14 views
6

私は最後にウェブサイトの統計情報を表示しようとしています。 私は過去30日間を掲載しました。GETDATE先月

CONVERT(VARCHAR(10), S.DATEENTERED, 101) 
    BETWEEN 
    CONVERT(VARCHAR(10), GETDATE()-30, 101) 
    AND 
    CONVERT(VARCHAR(10), GETDATE(), 101) 

と今月は、

RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) = 
RIGHT(CONVERT(VARCHAR(10), GETDATE(), 103), 7) 

しかし、先月にどのようなクエリを使用するかはわかりません。私は一緒に試みた。

RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) = 
RIGHT(CONVERT(VARCHAR(10), GETDATE()-1, 103), 7) 

は動作しませんでした。

答えて

11

以下は、あなたの最後の月の開始を見つける:

-- Start of last month 
SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),DATEADD(MONTH,-1,GETDATE()),113),8) AS datetime) 

その後、次、マイナス1を使用して、今月の開始を見つけるだろう。

-- Start of the month 
SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),GETDATE(),113),8) AS datetime) 

SQL Serverで日付を処理する必要がある場合は、よくRobyn Page's SQL Server DATE/TIME Workbenchと表示されます。ワークベンチ(チュートリアル)はうまくレイアウトされており、SQL Serverの日付を扱う際に必要なものはすべて含まれています。

2

DATEADD関数を使用してみてください。 MONTH(mm)datepartで-1を追加することができます。 Here is a link

1
where year(S.DATEENTERED) = year(dateadd(mm, -1, getdate())) and month(S.DATEENTERED) = month(dateadd(mm, -1, getdate())) 

パフォーマンスが良いわけではありませんが、あなたはそのアイディアを得ているかもしれません。

0

試してみてください。

declare @lastm int 
set @lastm = datepart(mm,getdate()) - 1 

...

where datepart(mm,s.dateentered) = @lastm 
+0

先月が去年になるとどうなるか考えてみましょう。 – GSerg

0

は先月の最初の日

SELECT DATEADD(MM, DATEDIFF(MM, '01/01/2000', DATEADD(MM, -1,GETDATE())), '01/01/2000') 

SELECT DATEADD(SS,-1,DATEADD(MM, DATEDIFF(MM,'01/01/2000',GETDATE()),'01/01/2000')) 
LAST月の最後の日をゲット

この範囲に基づいて検索します。

15

日付は、どのプログラミング言語でも動作する喜びであり、SQLは除外されません。特定の時間枠内のレコードを取得するための最良の手段を展開するには、先月

select S.DATEENTERED 
     ,* 
    from sometable S 
where S.DATEENTERED 
     between dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())), 0) 
      and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())) + 1, 0)) 
order by 1 

発生したすべてのレコードを見つけるためにあなたの質問に答えるために

はDATEDIFF関数、DATEADD関数との間を利用していますwhere句の条件。 00:00.000と先月の最後の可能な記録日付(最終日には、今日の日付が00 1900-01-01の間にあるかどうかを確認するためにチェックされているので

select 'howdy' 
     ,getdate() 
where getdate() 
     between dateadd(mm, 0, 0) 
      and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) 

上記のコードはレコードなしになりますが返さおよび23:59:59.997 - SQL Server DATETIME列の解像度は最大で3ミリ秒です)。

次のコードは、検索している日付が1か月前であるため、レコードを返します。

select 'howdy' 
     ,dateadd(mm, -1, getdate()) 
where dateadd(mm, -1, getdate()) 
     between dateadd(mm, 0, 0) 
      and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) 

where句のブレークダウン:

select dateadd(mm, 0, 0) as BeginningOfTime 
     ,dateadd(dd, datediff(dd, 0, getdate()), 0) as Today 
     ,dateadd(wk, datediff(wk, 0, getdate()), 0) as ThisWeekStart 
     ,dateadd(mm, datediff(mm, 0, getdate()), 0) as ThisMonthStart 
     ,dateadd(qq, datediff(qq, 0, getdate()), 0) as ThisQuarterStart 
     ,dateadd(yy, datediff(yy, 0, getdate()), 0) as ThisYearStart 
     ,dateadd(dd, datediff(dd, 0, getdate()) + 1, 0) as Tomorrow 
     ,dateadd(wk, datediff(wk, 0, getdate()) + 1, 0) as NextWeekStart 
     ,dateadd(mm, datediff(mm, 0, getdate()) + 1, 0) as NextMonthStart 
     ,dateadd(qq, datediff(qq, 0, getdate()) + 1, 0) as NextQuarterStart 
     ,dateadd(yy, datediff(yy, 0, getdate()) + 1, 0) as NextYearStart 
     ,dateadd(ms, -3, dateadd(dd, datediff(dd, 0, getdate()) + 1, 0)) as TodayEnd 
     ,dateadd(ms, -3, dateadd(wk, datediff(wk, 0, getdate()) + 1, 0)) as ThisWeekEnd 
     ,dateadd(ms, -3, dateadd(mm, datediff(mm, 0, getdate()) + 1, 0)) as ThisMonthEnd 
     ,dateadd(ms, -3, dateadd(qq, datediff(qq, 0, getdate()) + 1, 0)) as ThisQuarterEnd 
     ,dateadd(ms, -3, dateadd(yy, datediff(yy, 0, getdate()) + 1, 0)) as ThisYearEnd 

使用:

WHERE getdate() -- date to check 
between dateadd(mm, 0, 0) -- begin date 
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) -- end date 

最後に、日付の様々なここで、このように確認することができますが、かなり完全なリストであります上記のリストでは、任意のタイプの範囲を決定することができます。

+0

「SQL ServerのDATETIME列には、最大で3ミリ秒の分解能があります」ということは、あまり知られていません。私はこれまでに一度言及したこの宝石だけを聞いたことがある。素晴らしい詳細。 –

+0

詳細と非常に容認できる解決策のために+1を付ける。 –

4

BETWEEN use> =と<を使用するのではなく、先月の最初の日と当月の初日を使用することをお勧めします。それは私の個人的な意見ですが、このアプローチにはパフォーマンスと保守性のメリットがあると思います。

ここにSQLがあります。最後の月の値の最後の日が含まれていることに気づくでしょう。

これらの日付は、その日の午前12:00に基づいています。言い換えれば、値 6/1/2009と6/30/2009の間で得ることは、6/30/2009のすべてが除外されているので、あなたが望むものを得ることができません。 7月1日(2009年7月1日)の初日を使用する場合は、対象となります。

もう一度、以下のようにBETWEENを一緒に避けることをおすすめします。運が良かった。

Declare @LastMonthFirstDay datetime 
Declare @LastMonthLastDay datetime 
Declare @ThisMonthFirstDay datetime 

Set @LastMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 1, 0); 
Set @ThisMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0); 
Set @LastMonthLastDay = DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)); 

Select * From Table 
Where DateEntered >= @LastMonthFirstDay 
And DateEntered < @ThisMonthFirstDay; 
+0

境界日を変数に割り当てるアプローチは確かに保守性が高いと思います。しかし、私は、BETWEENがa> = よりも優れたパフォーマンスを示したという印象を受けました。 – ahsteele

+0

@ahsteele - あなたは正しいかもしれません。あなたが言及したように、「日付は一緒に働く喜びです」私は、クエリを変更する必要があることが判明しました。日付をフィルタリングする際に、できるだけ早く実行するようになるまでに何度もクエリを変更する必要がありました。私は>

6

これはいかがですか?

select DATEADD(month, -1, GETDATE()) 
+0

素晴らしい。一番短いクエリの+1 – BNN

関連する問題