SQL Server - 查找最多订单的前n个顾客

3

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

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个客户。请修正一下。 - undefined
因为我想显示前两位顾客下的所有订单。 - undefined
如果第二个位置有两条记录,那么会发生什么?你会选择哪一条? - undefined
7个回答

3

这里是展示以下代码可行的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只有一个订单(两条记录的orderId都是9),但是这个子查询将会把顾客102视为有两个订单。 - undefined
@rsbarro,你是对的,这是不完全正确的,我必须在计数时添加DISTINCT,如下所示:ORDER BY COUNT(DISTINCT COS.orderId) - undefined
我更新了我的回答以反映这些问题,现在如果订单ID出现多次,您将获得正确的结果。 - undefined
@iniki 我认为COUNT(DISTINCT)是一个可行的方法。我更新了我的答案,使用了这种方法,将查询限制在只有1个子查询中。 - undefined

1

试试这个:

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

1

我会使用子查询来查找订单最多的客户。以下是一个可行的示例:

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

在子查询中,我添加了一个次要排序以打破订单数量的平局。

看起来这个可能不会正常工作。查询结果中显示了多个OrderID。这里是显示问题的SQL Fiddle - undefined
+1 你的解决方案也有效。;) 我们都忽略了类似的东西。 - undefined
是的,不管出于什么原因,这个问题比看起来的要难一些。:) 我也给你的答案点了赞。 - undefined

0
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

0
select customername from customers where customerid  in 
   (select top 2 customerid from 
       (select count(*), customerid FROM orders
        group by customerid
        order by count(*) DESC))

0
with CustomerOrders as
(
select CustomerId, count(orderId) as NoOfOrders
from dbo.CustomerOrder
group by CustomerId
)
select top 2 * from CustomerOrders
order by NoOfOrders desc

0
select customerid,orderid from customerOrders 
group by CustomerId,OrderId 
having count(orderid) =1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接