我需要帮助构建一个SQL查询,该查询返回仅订购一次的客户的订单。
表格和相关字段如下:
Order Customer
------- -----------
orderId customerId
orderDate
customerId
etc.
我正在查找订单记录的结果集,其中只有一个客户ID出现。对于以下数据集......
[orderId] [customerId] [orderDate] [etc.]
---------- ------------ ------------ ------------
o1 c1 1/1/14 foo
o2 c2 1/1/14 baz
o3 c3 1/3/14 bar
o4 c2 1/3/14 wibble
我希望结果是
[orderId] [orderDate] [etc.]
--------- ----------- ------
o1 1/1/14 foo
o3 1/3/14 bar
订单o2和o4被省略,因为c2订购了两次。
非常感谢任何帮助。
对不起,没有尝试失败。这就是我试过的......
SELECT customerId,
orderId,
orderDate,
Count(*)
FROM Orders
GROUP BY orderId,
orderDate,
customerID
HAVING Count(*) = 1
ORDER BY orderId
它似乎会返回所有订单。
答案 0 :(得分:14)
尝试以下方法(假设SQL Server 2005 +):
;WITH CTE AS
(
SELECT *,
N = COUNT(*) OVER(PARTITION BY customerId)
FROM Orders
)
SELECT *
FROM CTE
WHERE N = 1
由于有时候行人方法比复杂的CTE更受欢迎,你可以根据需要使用派生表(但由于它使用OVER
子句,你仍然需要SQL Server 2005 +):
SELECT *
FROM ( SELECT *,
N = COUNT(*) OVER(PARTITION BY customerId)
FROM Orders) T
WHERE N = 1
或者(例如,如果您使用的是旧版本的SQL-Server),您可以使用GROUP BY / HAVING COUNT(*)=1
方法查找只有1个订单的客户,然后再加入Orders
table(不需要所有列中的聚合函数):
SELECT o.*
FROM Orders o
JOIN
( SELECT customerId
FROM Orders
GROUP BY customerId
HAVING COUNT(*) = 1
) c
ON c.customerId = o.customerId ;
或使用NOT EXISTS
(不需要COUNT()
,它甚至可以在MySQL中运行):
SELECT o.*
FROM Orders o
WHERE NOT EXISTS
( SELECT 1
FROM Orders c
WHERE c.customerId = o.customerId
AND c.orderId <> o.orderId
) ;
答案 1 :(得分:2)
这将列出ORDERS
表中的所有首次客户。
SELECT [customerID],
MIN([orderId]) AS [orderId],
MIN([orderDate]) AS [orderDate],
MIN([etc.]) AS [etc.]
FROM [Orders]
GROUP BY [customerID]
HAVING Count(*) = 1
ORDER BY [customerID]
为了恢复所有其他列,您需要将它们包装在聚合中,例如MIN/MAX
。
使用是任意的,因为每组只有一行。这确实假设表中的所有列都具有对此类聚合有效的数据类型(不是BIT
或XML
的数据类型示例)