【问题标题】:SQL needs group by, but i dont see how it appliesSQL 需要分组,但我不明白它是如何应用的
【发布时间】:2016-03-06 20:23:31
【问题描述】:

我试了很多次都没有成功。

问题是

  1. 列出在 2014 年下达 2 个或更多订单的安大略省客户的客户 ID

我的答案是

SELECT Customer.CustId 
FROM Customer 
   INNER JOIN Orders ON Customer.CustId = Orders.CustId 
WHERE (Prov = 'ON' AND YEAR( Orders.OrderDate) = '2014') 
HAVING COUNT (Orders.CustId) > 2;

但我不断收到错误,因为没有 group by 子句,但我不知道答案会在哪里发挥作用。

附上物理架构

http://imgur.com/hbosBDM

【问题讨论】:

  • 可以以当前格式回答问题(编辑后),但最好将表模式包含为文本,而不是图像。对于更复杂的问题,如果我们能够实际测试查询(创建表、运行脚本),您会得到更好的答案。

标签: sql sql-server group-by


【解决方案1】:

HAVING 仅与 GROUP BY 结合使用。只需将 COUNT(...) > 2 作为 WHERE 子句的一部分。所以你的查询看起来像:

SELECT Customer.CustId 
FROM Customer 
   INNER JOIN Orders ON Customer.CustId = Orders.CustId 
WHERE (Prov = 'ON' AND YEAR( Orders.OrderDate) = '2014') AND COUNT (Orders.CustId) > 2;

【讨论】:

    【解决方案2】:

    这个错误是有道理的,因为 HAVING 子句仅在分组时应用 (GROUP BY)。应该工作的查询版本如下:

    SELECT Customer.CustId, COUNT(1) Cnt
    FROM Customer C
       INNER JOIN Orders O ON C.CustId = O.CustId 
    GROUP BY C.CustId
    WHERE Prov = 'ON' AND YEAR(Orders.OrderDate) = 2014 
    HAVING COUNT (1) > 2;
    

    为了稍微优化一下,你应该避免在条件中使用标量函数,因为该列上的任何索引都不能使用:

    SELECT Customer.CustId, COUNT(1) Cnt
    FROM Customer C
       INNER JOIN Orders O ON C.CustId = O.CustId 
    GROUP BY C.CustId
    WHERE Prov = 'ON' AND (Orders.OrderDate BETWEEN '20140101' AND '20141231') 
    HAVING COUNT(1) > 2;
    

    【讨论】:

      【解决方案3】:
      SELECT Customer.CustId 
      FROM Customer 
         INNER JOIN Orders ON Customer.CustId = Orders.CustId 
      WHERE (Prov = 'ON' AND YEAR(Orders.OrderDate) = 2014) 
      GROUP BY Customer.CustId   --<-- you need to add this group by here 
      HAVING COUNT (Orders.CustId) > 2;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-19
        • 1970-01-01
        相关资源
        最近更新 更多