2016-06-20 118 views
1

我需要查詢SQL的數據落入上個月的日期。我以爲我使用正確的查詢邏輯,但我沒有得到任何結果,我知道有結果。代碼片段是這樣的:SQL查詢減1個月

MONTH(n.JOIN_DATE) = DATEADD(month, - 1, GETDATE()) 

這給我沒有結果,我需要得到任何有上個月加入日期的人。我錯過了什麼?

+1

你能顯示你的完整查詢嗎? –

+0

還有一些示例數據會很好。 –

+4

'MONTH()'返回一個月份號碼。 'DATEADD()'返回一個日期。一個月永遠不會等同於一個日期。 –

回答

1

MONTH(n.JOIN_DATE)將僅返回月份的數值(例如:115)。

DATEADD(MONTH, -1, GETDATE())將簡單地從當前日期減去一個月。它仍然是DATETIME格式。

你可能會尋找:

MONTH(n.JOIN_DATE) = MONTH(DATEADD(MONTH, -1, GETDATE())) 
3

使用此:

MONTH(n.JOIN_DATE) = MONTH(DATEADD(month, - 1, GETDATE())) 

你需要與蘋果比較蘋果,所以數值比較每月在等式的兩邊。

在我做這件事之前,爲了解決這個問題,我大量贊助@PaulL。

更新:

由於@DasBlinkenLight和馬特指出,僅僅靠一個月比較敞開了大門要返回多年。一種可能的解決辦法是比較幾年,例如

WHERE MONTH(n.JOIN_DATE) = MONTH(DATEADD(month, - 1, GETDATE())) AND 
     YEAR(n.JOIN_DATE) = YEAR(DATEADD(month, - 1, GETDATE())) 
+0

如果數據集中存在超過1年,則會返回多年的結果。如果你還添加AND AND YEAR(n.JOIN_DATE)= YEAR(DATEADD(year,-1,GETDATE())將會解決這個問題 – Matt

1

MONTH(...)產生一個月數。您不應該將其與DATEADD返回的結果進行比較,該結果實際上是一個日期。

如果您正在尋找大家誰已經不到一個月前加入,你可以做這樣的:

WHERE DATEADD(month, 1, n.JOIN_DATE) > GETDATE() 

這是考慮到今年與天爲好,不僅月份。

如果您正在尋找大家誰上個月參加,在那一天沒有事,你可以使用更復雜的條件:

WHERE MONTH(DATEADD(month, -1, GETDATE()) = MONTH(n.JOIN_DATE) 
    AND YEAR (DATEADD(month, -1, GETDATE()) = YEAR (n.JOIN_DATE) 

第二個條件是必要的,以避免成員之間的混淆加盟上個月成員在一年或更多年前的同一個月加入。

-2

對此答案的回覆是正確的。但是根據最佳實踐來編寫查詢,這種方式會使得查詢不那麼可靠,因此如果您有查詢,就會忽略索引。它可能會更好地寫爲

WHERE n.JOIN_DATE between DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) AND DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1) 

基於下面的評論我已修改查詢。我想我沒有深入地讀過這個問題。

+0

如果我今天運行,2016-06-20,它不會返回2016- 05-02,它應該,但會返回2016-06-03,它不應該。相應地downvoted。 –

+0

返回到您的早期版本DATEADD(month,-1,GETDATE())和GETDATE()。一個返回了5/20到6/20的正確日期範圍,這個返回6/1到5/31 23:59:59.000這是錯誤的順序和不正確的日期我不知道什麼@ DanBracuk打字是爲了得到他的結果 – Matt

+0

這個問題說他想要在上個月有所下降,這是我假設的5/20範圍還是我誤解了? – damola

1
MONTH(n.JOIN_DATE) returns a numeric which indicate the month in date m.JOIN_DATE 
DATEADD(month, - 1, GETDATE()) returns a date which indicate date in last month. 
So, you can use this instead : 
MONTH(n.JOIN_DATE)= MONTH(DATEADD(month, - 1, GETDATE())) 
OR 
n.JOIN_DATE = DATEADD(month, - 1, GETDATE()) 
+0

您需要一個介於或大於小於的距離才能得到他所有的結果,而不僅僅是一天 – Matt

+0

此外,如果他的列中有時間組件 – Matt

0
SELECT 
    DATEFROMPARTS(YEAR(DATEADD(month,-1,GETDATE())),MONTH(DATEADD(month,-1,GETDATE())),1) AS StartOfLastMonth 
    ,DATEADD(day,-1,(DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()),1))) AS EndOfLastMonthAsDate 
    ,DATEADD(day,-3,CAST(DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()),1) AS DATETIME)) AS EndOfLastMonthMidngith 
    ,CAST(DATEADD(month,-1,GETDATE()) AS DATE) AS OneMonthAgoStrartOfDay 
    ,CAST(GETDATE() AS DATE) AS StartOfToday 
    ,DATEADD(MS,-3,CAST(CAST(GETDATE() AS DATE) AS DATETIME)) AS MidnightLastNight 

沒關係,人們肯定說明有很多不同的答案,你的問題並都在類似的前提下建造的。使用DATEADD()與一個負數回去一個月。或者比較月份和年份,看看它們是否相同。前者是在1個月前到今天,後者是在上個月。

所有的答案到目前爲止,預計@DasBlinkenLight和@TimBiegeleisen,失敗,如果你有一個要考慮到你列的TIME組件和GETDATE()功能。如果您的專欄是DATETIME,您需要考慮這一點。以上SELECT查詢,將通過一些方法來達到我懷疑將滿足您的需求的不同日期。

至於使用BETWEEN日期要小心!因爲你輸入的數值是包含性的,所以如果你將GETDATE()置於中間語句的右邊,你也會得到今天的結果,但是你可能真的想要達到今天,在這種情況下你應該改變你的右邊參數。另外我不確定Oracle,mysql等,但Micrsofot SQL-Server精確到.003毫秒。所以如果你真的想看一個日期的午夜,你應該看看23:59:59.997,因爲.998和.999會在第二天結束。

同樣爲了進一步簡化,如果你不想要時間組件,你也可以把你的專欄投到DATE,並且它基本上沒有時間和BETWEEN,因爲有一點更清晰,例如, CAST(n.JOIN_DATE AS DATE)

在這個問題上肯定還有其他的問題,我鼓勵你研究。

-1

我知道這是一個簡單的,我錯過了一些東西。我的代碼是錯誤的,因爲我收到了很多回應,並且我正在比較蘋果和橙子,而不是蘋果。一旦我在dateadd函數週圍添加了Month(),它就起作用了。

+0

請注意您的數據何時包含多年。如果你想要上個月的所有時間,你需要比較上個月的YEAR和你的n.JOIN_DATE和這個月的YEAR。否則,如果你的數據有多年,你會在結果中的每一年獲得該月的數據 – Matt