如何编写SQL查询以匹配同一列中的两个条件?

时间:2015-11-30 12:53:29

标签: sql sql-server

我正在使用AdventureWorks2014数据库,需要为2011年和2014年两年下订单的客户检索客户的ID。到目前为止,我有这样的查询:

operator new(std::size_t, int, int, int)

当我尝试运行它时,我收到一个错误:

  

列'Sales.SalesOrderHeader.CustomerID'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

我尝试添加SELECT CustomerID, SalesOrderID, YEAR(OrderDate) AS 'Year' FROM Sales.SalesOrderHeader WHERE YEAR(OrderDate) IN (2011,2014) HAVING COUNT(YEAR(OrderDate))=2; GROUP BY,但这导致了一个空表。我不一定需要使用ORDER BY,这只是我提出的一个想法。有没有办法列出2011年和2014年重复的CustomerID?我被困了,也许我看不到简单的事情?

编辑:我真的需要同时选择SalesOrderID和Year,而不仅仅是CustomerID。那通常是我遇到麻烦的地方。

4 个答案:

答案 0 :(得分:3)

您必须在COUNT中使用GROUP BY CustomerID和DISTINCT关键字,才能只计算2014年的一个和2011年的一个(如果每年订单数量很多的话):

SELECT CustomerID
FROM Sales.SalesOrderHeader 
WHERE YEAR(OrderDate) IN (2011,2014)
GROUP BY CustomerID 
HAVING COUNT(DISTINCT YEAR(OrderDate))=2;

要为这些客户选择所有订单,请尝试以下操作:

SELECT CustomerID, SalesOrderID, YEAR(OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader 
WHERE CustomerID IN
   (SELECT CustomerID
    FROM Sales.SalesOrderHeader 
    WHERE YEAR(OrderDate) IN (2011,2014)
    GROUP BY CustomerID 
    HAVING COUNT(DISTINCT YEAR(OrderDate))=2
   )

或者使用@ dasblinkenlight的答案中的JOIN语法。

答案 1 :(得分:2)

您的查询在相同列上具有条件,但结果将在不同的行中。有两种方式可以通过多种方式查询已购买的客户记录,无论是否有GROUP BY

以下是使用两个相关子查询的简单方法:

SELECT CustomerID, SalesOrderID, YEAR(OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader t
WHERE
    EXISTS (
        SELECT * FROM Sales.SalesOrderHeader h
        WHERE t.CustomerID=h.CustomerID AND YEAR(OrderDate)=2011
    )
    AND
    EXISTS (
        SELECT * FROM Sales.SalesOrderHeader h
        WHERE t.CustomerID=h.CustomerID AND YEAR(OrderDate)=2014
    )

以下是使用GROUP BY的另一种方式:

SELECT CustomerID, SalesOrderID, YEAR(OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader t
JOIN (
    SELECT CustomerID
    FROM Sales.SalesOrderHeader
    WHERE YEAR(OrderDate) IN (2011,2014)
    GROUP BY CustomerID, YEAR(OrderDate)
    HAVING COUNT(*)=2
) h ON h.CustomerID=t.CustomerID

"嵌套"查询,用于检索我们感兴趣的CustomerID,与您的查询非常相似。

答案 2 :(得分:0)

尝试此操作,只有在2011年和2014年购买时才会返回匹配的客户ID

SELECT S.CustomerID, S.SalesOrderID, YEAR(S.OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader S 
  WHERE S.CustomerId IN (
       SELECT DISTINCT S1.CustomerId FROM Sales.SalesOrderHeader S1
         INNER JOIN Sales.SalesOrderHeader S2 ON S1.CustomerID = S2.CustomerId
         WHERE YEAR(S1.OrderDate) = 2011 AND YEAR(S2.OrderDate) = 2014)
      AND YEAR(S.OrderDate) IN (2011,2014)

答案 3 :(得分:0)

执行所需操作的一种非常简单的方法是使用窗口函数:

SELECT soh.CustomerID, soh.SalesOrderID, YEAR(soh.OrderDate) AS [Year]
FROM (SELECT soh.*,
             MIN(YEAR(OrderDate)) OVER () as miny,
             MAX(YEAR(OrderDate)) OVER () as maxy
      FROM Sales.SalesOrderHeader soh
      WHERE YEAR(OrderDate) IN (2011, 2014)
     ) soh
WHERE miny < maxy;