【问题标题】:SQL Statement Help - Select list of CustomerID, OrderDate with the most records in a tableSQL 语句帮助 - 选择表中记录最多的 CustomerID、OrderDate 列表
【发布时间】:2008-12-07 10:27:12
【问题描述】:

我将使用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,Life is Good®。 :)

【问题讨论】:

    标签: sql sql-server-2005


    【解决方案1】:

    您应该使用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 表达式之前是必需的。

    【讨论】:

    • 我已经测试了这个 SQL,它运行良好!最后的 WHERE 语句是我悲伤的主要来源,因为我无法找到引用 Max(Cnt) 值的方法。谢谢!
    【解决方案2】:

    我没有可以方便地测试的 AdventureWorks 副本,但是 WITH TIES 子句可以提供帮助吗?你可以这样做:

    SELECT TOP 1 WITH TIES CustomerID, OrderDate, COUNT(*) Cnt
    ...
    ORDER BY COUNT(*) DESC
    

    ... 这应该会为您提供与您的 ORDER BY 子句中的值匹配的所有行(计数)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 2010-09-26
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      相关资源
      最近更新 更多