从首次购买客户中选择订单

时间:2014-02-04 17:44:50

标签: sql sql-server select

我需要帮助构建一个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 

它似乎会返回所有订单。

2 个答案:

答案 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

使用是任意的,因为每组只有一行。这确实假设表中的所有列都具有对此类聚合有效的数据类型(不是BITXML的数据类型示例)