2012-12-11 80 views
2

感謝您花時間幫助我!我試圖讓SQL做一些我認爲對於任何知道SQL的人來說都很容易,但是在這一點上,我正在打我的頭。如何選擇由max()命令返回的記錄中的另一條數據

我有我一張小桌子像這樣 -

Update Order UpdateDate    OrderDate 
9297 3590 2012-12-06     2012-12-06 
9298 3590 2012-12-06     2012-12-06 
9356 3590 2012-12-07     2012-12-06 
9369 3590 2012-12-08     2012-12-06 
9381 3590 2012-12-10     2012-12-06 

我的目標是要找到那些沒有在過去的3天被更新的訂單。

醜陋的版本是我想要做的就是這樣的事情 -

Select order from orderstable 
where cast(max(updatedate)-getdate() as int) >3 

這裏的目標是讓那些沒有在過去的3天被更新的命令返回「訂單」。我目前的問題是我不知道如何讓SQL專注於訂單的「最新」更新。

+1

請澄清你的問題。您是否要求在過去三天內沒有更新的訂單?或者在訂單日期的三天內沒有更新的訂單?你的文字表明它是第一個,你的查詢努力顯示它是第二個。 –

+0

對不起,我感到困惑。我正在嘗試查找在過去3天內未更新的訂單,因此您的示例文本看起來是錯誤的... –

回答

2

最簡單的方法就是一個日期比較:

select * 
from orderstable ot 
where datediff(day, updatedate, getdate()) > 3 

我看到,每個訂單都有多個記錄,並且您希望在過去三天內沒有更新的訂單。

select distinct order 
from orderstable 
where order not in (select order 
        from orderstable 
        where datediff(day, updatedate, getdate()) <= 3) 
+0

對不起,我的示例有點不合適...我現在修復了它。我目前遇到的問題是,我的查詢將返回訂單3590,因爲它看到今天的日期減去第一個記錄中的日期大於3.我試圖讓它只使用「最近的」更新當做數學。 –

+1

+1,你的彙總版本的「有條件」也可以這樣寫:'datediff(day,max(updatedate),getdate())> 3'(可能對某些人來說看起來稍微直截了當,堅持)。 –

+0

感謝您的幫助,這是做到了! –

0

爲什麼不使用getdate()獲取當前日期?

因此,像這樣:

SELECT order FROM orderstable 
WHERE datediff(day, updatedate, getdate()) > 3 

(是的,這並沒有回答的題目問的問題 - 但它確實回答問題的身體所造成的問題)

要回答這個問題在標題問,怎麼樣:

SELECT order FROM orderstable 
WHERE datediff(day, orderdate, (select max(updatedate) from orderstable)) > 3 
1

首先,我會避免:

select order 
from orderstable ot 
group by order 
having min(datediff(day, updatedate, getdate())) > 3 

您也可以通過查找沒有更新在最後三天的訂單做到這一點:我會繼續聚集做使用DATEDIFF因爲它不是可優化搜索:http://weblogs.sqlteam.com/dang/archive/2009/03/07/Low-Hanging-Fruit-of-Sargable-Expressions.aspx

;WITH MaxOrders AS (
     SELECT Order, MAX(UpdateDate) MaxUpdateDate 
     FROM orderstable 
     GROUP BY Order 

    ) 

    SELECT Order 
    FROM MaxOrders 
    WHERE MaxUpdateDate < DATEADD(day,-3,GETDATE()); 

在這個例子中,是DATEADD可優化搜索,因爲有一個靜態值,GETDATE(),在函數。如果函數中有列值,它不會是可靠的。換句話說,如果你把它改成這樣:

WHERE DATEADD(day,3,MaxUpdateDate) < GETDATE(); 

它將不再是優化搜索,因爲所有的列值都必須在功能的匹配標準確定之前評估。這是在where子句中使用DATEDIFF的問題。它具有函數中的列值。在大數據集上這將會非常昂貴。

+0

感謝這些信息,我從來沒有聽說過Sargable,這是一個非常有趣的閱讀。 –

0
DECLARE @T TABLE(
[Update] INT, 
[Order] INT, 
UpdateDate DATE, 
OrderDate DATE 
) 

INSERT INTO @T VALUES 
(9297,3590,'2012-12-06','2012-12-06'), 
(9298,3590,'2012-12-06','2012-12-06'), 
(9356,3590,'2012-12-07','2012-12-06'), 
(9369,3590,'2012-12-08','2012-12-06'), 
(9381,3590,'2012-12-10','2012-12-06'), 
(9382,3591,'2012-12-07','2012-12-06'), 
(9383,3591,'2012-12-08','2012-12-06'), 
(9384,3592,'2012-12-07','2012-12-06'), 
(9385,3592,'2012-12-09','2012-12-06'), 
(9386,3593,'2012-12-05','2012-12-06'), 
(9387,3593,'2012-12-07','2012-12-06')  


--Assuming we don't care about time, cast to DATE to remove time values from GETDATE() function. 
--It also assumes that today is inclusive. 
;WITH RECENT_UPDATES_CTE 
AS (
    SELECT [Order],MAX([UpdateDate]) [LastUpdateDate] FROM @T 
    GROUP BY [Order] 
) 
SELECT DISTINCT T.[Order] FROM @T T 
LEFT JOIN RECENT_UPDATES_CTE C ON C.[Order] = T.[Order] 
WHERE C.LastUpdateDate <= DATEADD(DAY,-3,CAST(GETDATE() AS DATE)) 
+0

這一個應該工作,但似乎不必要的複雜。您不需要從原始數據集('@ T')中選擇不同的'Order'值,因爲您已經消除了'RECENT_UPDATES_CTE'中的重複項,所以只需從那裏讀取'Order'而不涉及'@ T'任何更多。另外請注意,在WHERE子句中使用左連接的右側列可以有效地將外連接變爲內連接,因爲任何NULL(如果可能)都會在'=','<','<='等中被刪除。比較(就是說,使用LEFT JOIN時,它可能會令人困惑,因爲它並不真正起作用)。 –

0

使用OVER子句發現MAX(UpdateDate)

;WITH cte AS 
(  
    SELECT *, 
     DATEDIFF(d, MAX(UpdateDate) OVER (PARTITION BY [Order]), GETDATE()) AS diff_date 
    FROM orderstable 
) 
    SELECT [Update], [Order], UpdateDate, OrderDate 
    FROM cte 
    WHERE diff_date > 3 

演示上SQLFiddle

相關問題