【问题标题】:SQL Server - Find Top n customers with maximum ordersSQL Server - 查找订单最多的前 n 个客户
【发布时间】:2013-11-08 00:07:49
【问题描述】:

我想找到订单最多的前 2 位客户。
表格如下:

CustomerId  OrderId ProductId
101         1       A
101         3       B
101         4       C
102         9       D
102         9       E
103         11      E
103         22      F

这是我需要的 SELECT 查询的输出:

CustomerId  OrderId 
101         1
101         3
101         4
103         11
103         22  

解决方案只是没有点击我的想法......我已经使用以下查询达到了一半 -

SELECT CustomerId, OrderId
FROM dbo.CustomerOrder
GROUP BY CustomerId, OrderId

这只是给了我不同的 CustomerId、OrderId 对。

谁能帮忙。

【问题讨论】:

  • 在您想要的结果中,101 出现了 3 次,但您说您只想要前 2 个客户。请修复。
  • 因为我想显示前 2 位客户下的所有订单
  • 如果你有 2 条记录在第二位会发生什么?你选择哪一个? ——

标签: sql sql-server join subquery inner-join


【解决方案1】:
with CustomerOrders as
(
select CustomerId, count(orderId) as NoOfOrders
from dbo.CustomerOrder
group by CustomerId
)
select top 2 * from CustomerOrders
order by NoOfOrders desc

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT c.CustomerId, c.OrderId
    FROM CustomerOrder c
    INNER JOIN
    (SELECT TOP 2 WITH TIES CustomerId, COUNT(distinct OrderId) as Count
    FROM CustomerOrder
    GROUP BY CustomerId
    ORDER BY Count DESC) b ON c.CustomerId = b.CustomerId
    

    您可以使用 WITH TIES,例如,如果您有 3 个客户的最大订单数量相同,WITH TIES 将检索这三个,没有这个您将让一个外面,这可能是错误的。

    查看SQL FIDDLE DEMO

    【讨论】:

      【解决方案3】:

      我会使用子选择来查找订单最多的客户。这是一个工作示例:

      DECLARE @orders AS TABLE(CustomerId INT, OrderId INT, ProductId VARCHAR(10))
      INSERT INTO @orders VALUES(101, 1, 'A')
      INSERT INTO @orders VALUES(101, 3, 'B')
      INSERT INTO @orders VALUES(101, 4, 'C')
      INSERT INTO @orders VALUES(102, 9, 'D')
      INSERT INTO @orders VALUES(102, 9, 'E')
      INSERT INTO @orders VALUES(103, 11, 'E')
      INSERT INTO @orders VALUES(103, 22, 'F')
      
      SELECT DISTINCT
          O.CustomerId,
          O.OrderId
      FROM @orders O
      JOIN (
          SELECT TOP 2 CustomerId, COUNT(DISTINCT(OrderId)) as OrderCount
          FROM @orders
          GROUP BY CustomerId
          ORDER BY COUNT(DISTINCT(OrderId)) DESC, CustomerId
      ) O2 ON O2.CustomerId = O.CustomerId
      ORDER BY O.CustomerId, O.OrderId
      

      在子选择中,我添加了二级排序来打破订单数量的关系。

      【讨论】:

      • 这似乎无法正常工作。它在查询结果中显示多个OrderIDs。这是显示问题的SQL Fiddle
      • +1 您的解决方案同样有效。 ;) 我们都缺少相似的东西。
      • 是的,无论出于何种原因,这个问题比看起来要难一些。 :) 我也为你的回答 +1。
      【解决方案4】:

      这是SQL Fiddle 示例,它显示了以下代码的工作原理:

      SELECT DISTINCT CO.CustomerId, CO.OrderID FROM 
      (
        SELECT TOP(2) COS.CustomerId, COUNT(DISTINCT COS.orderId) as NoOfOrders
        FROM custorders AS COS
        GROUP BY COS.CustomerId
        ORDER BY COUNT(DISTINCT COS.orderId) DESC, CustomerId  DESC
      ) AS COM 
      INNER JOIN custorders AS CO
        ON COM.CustomerId = CO.CustomerId
      

      【讨论】:

      • 我不认为这个答案是正确的,尽管它确实产生了正确的结果。您可以通过切换客户 102 和 103 的订单来打破这个答案。问题是客户 102 只有 1 个订单(两条记录都是 orderId 9),但是此子选择会将客户 102 视为有 2 个订单。
      • @rsbarro,你说得对,这并不完全正确,我必须在计数时添加 DISTINCT:ORDER BY COUNT(DISTINCT COS.orderId)
      • 我更新了我的答案以反映问题,如果订单 ID 多次显示,您现在将获得正确的结果。
      • @iniki 我认为COUNT(DISTINCT) 是要走的路。我更新了我的答案以使用将查询限制为仅 1 个子选择的方法。
      【解决方案5】:
      select customername from customers where customerid  in 
         (select top 2 customerid from 
             (select count(*), customerid FROM orders
              group by customerid
              order by count(*) DESC))
      

      【讨论】:

        【解决方案6】:
        SELECT customer.cust_name, order.order_amount
        FROM customer inner join order
        ON customer.cust_id = order.cust_id
        ORDER BY order.order_amount DESC
        

        【讨论】:

          【解决方案7】:
          select customerid,orderid from customerOrders 
          group by CustomerId,OrderId 
          having count(orderid) =1
          

          【讨论】:

            猜你喜欢
            • 2021-04-09
            • 2013-11-22
            • 1970-01-01
            • 2022-07-01
            • 1970-01-01
            • 2017-07-08
            • 1970-01-01
            • 2013-05-05
            • 2014-12-11
            相关资源
            最近更新 更多