我将使用AdventureWorks Database来说明我的问题。
我需要为特定客户显示包含最多订单的OrderDate列表。
我的尝试如下:
SELECT CustomerID, OrderDate, COUNT(1) Cnt
FROM Sales.SalesOrderHeader
WHERE CustomerID = 11300
GROUP BY CustomerID, OrderDate
ORDER BY Cnt DESC
这将得到以下结果:
CustomerID OrderDate Cnt
----------- ---------- ----
11300 2003-11-22 00:00:00.000 2
11300 2004-01-28 00:00:00.000 2
11300 2004-02-18 00:00:00.000 2
11300 2004-02-08 00:00:00.000 2
11300 2004-02-15 00:00:00.000 1
11300 2004-03-11 00:00:00.000 1
11300 2004-03-24 00:00:00.000 1
11300 2004-03-30 00:00:00.000 1
11300 2004-04-28 00:00:00.000 1
11300 2004-05-03 00:00:00.000 1
11300 2004-05-17 00:00:00.000 1
11300 2004-06-18 00:00:00.000 1
...
不完全是我想要的,因为结果应该只显示Cnt = 2的所有记录,如下所示:
CustomerID OrderDate Cnt
----------- ---------- ----
11300 2003-11-22 00:00:00.000 2
11300 2004-01-28 00:00:00.000 2
11300 2004-02-18 00:00:00.000 2
11300 2004-02-08 00:00:00.000 2
我被困了,因为我无法解决两个问题:
1)客户可能有多个具有相同Cnt值的OrderDate。这意味着我不能做像TOP 1这样的事情来获得理想的结果 2)因为每个客户的订单数量可能不同,所以我不能使用以下SQL语句:
SELECT CustomerID, OrderDate, COUNT(1) Cnt
FROM Sales.SalesOrderHeader
WHERE CustomerID = 11300
GROUP BY CustomerID, OrderDate HAVING COUNT(1) > 1
ORDER BY Cnt DESC
这将有助于为该客户获得正确的结果,但如果下一个客户在特定日期只有一个订单,那肯定会出错。
因此,在这种情况下查询是不可能的,或者我以错误的方式接近查询。关于这个问题的任何想法表示赞赏。
此外,由于这将是存储过程中的查询,因此在T-SQL中解决此问题的任何想法都是可以接受的。
更新:感谢Mehrdad,我被介绍到Common Table Expressions,而LifeisGood®。 :)
答案 0 :(得分:3)
您应该使用TOP
n
WITH TIES
子句来完成任务:
SELECT TOP 1 WITH TIES CustomerID, OrderDate, COUNT(*) Cnt
FROM Sales.SalesOrderHeader
WHERE CustomerID = 11300
GROUP BY CustomerID, OrderDate
ORDER BY Cnt DESC
或者,您可以使用公用表表达式(CTE)来解决问题。此解决方案需要SQL Server 2005或更高版本:
WITH MyTable AS (SELECT CustomerID, OrderDate, COUNT(*) Cnt
FROM Sales.SalesOrderHeader
WHERE CustomerID = 11300
GROUP BY CustomerID, OrderDate)
SELECT CustomerID, OrderDate, Cnt
FROM MyTable
WHERE Cnt = (SELECT MAX(Cnt) FROM MyTable);
如果您正在使用CTE方法,请确保先前的语句以分号结束(如果它不是第一个语句)。在CTE表达之前需要它。
答案 1 :(得分:1)
我没有使用的AdventureWorks副本,但是WITH TIES子句可以帮忙吗?你可以这样做:
SELECT TOP 1 WITH TIES CustomerID, OrderDate, COUNT(*) Cnt
...
ORDER BY COUNT(*) DESC
...它应该为您提供与ORDER BY子句中的值匹配的所有行(计数)。