2

感谢您花时间帮助我!我正在尝试让 SQL 做一些我认为对于任何了解 SQL 的人来说都很容易的事情,但此时我正在努力应对。

我有一张像这样的小桌子-

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 只关注订单的“最新”更新。

4

5 回答 5

2

最简单的方法是日期比较:

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

我明白了,您对每个订单都有多条记录,并且您想要在过去三天内没有更新的订单。我会用聚合来做到这一点:

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

您也可以通过查找过去三天内没有更新的订单来做到这一点:

select distinct order
from orderstable
where order not in (select order
                    from orderstable
                    where datediff(day, updatedate, getdate()) <= 3)
于 2012-12-11T01:31:11.010 回答
1

首先,我会避免使用 DATEDIFF,因为它不是 sargable: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()。如果函数中包含列值,则它不会是 sargable。换句话说,如果您将其更改为:

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

它不再是 sargable,因为在确定标准匹配之前,必须在函数中评估所有列值。这是在 where 子句中使用 DATEDIFF 的问题。它在函数中有列值。这在大数据集上将非常昂贵。

于 2012-12-11T01:57:04.953 回答
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))
于 2012-12-11T05:23:24.983 回答
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
于 2012-12-11T01:30:57.120 回答
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上的演示

于 2012-12-11T08:08:40.830 回答