【问题标题】:SQL - WHERE Condition on SUM()SQL - SUM() 上的 WHERE 条件
【发布时间】:2013-03-16 15:43:19
【问题描述】:

是否可以这样做:

SELECT 
  `e`.*, 
  `rt`.`review_id`, 
  (SUM(vt.percent) / COUNT(vt.percent)) AS rating 
FROM `catalog_product_entity` AS `e` 
INNER JOIN `rating_option_vote` AS `vt`
  ON vt.review_id = e.review_id 
WHERE (rating >= '0') 
GROUP BY `vt`.`review_id`

我特别想在除法结果值上加上 where 条件

【问题讨论】:

    标签: mysql sql sum conditional-statements


    【解决方案1】:

    这可以通过 HAVING 子句来完成:

    SELECT e.*, rt.review_id, (SUM(vt.percent) / COUNT(vt.percent)) AS rating 
    FROM catalog_product_entity AS e 
    INNER JOIN rating_option_vote AS vt ON e.review_id = vt.review_id 
    GROUP BY vt.review_id
    HAVING (SUM(vt.percent) / COUNT(vt.percent)) >= 0
    ORDER BY (SUM(vt.percent) / COUNT(vt.percent)) ASC
    

    注意:添加了 ORDER BY 语句的放置位置

    查询优化器也不应该多次计算平均值,所以这里不应该担心。

    正如@jagra 的回答中提到的,您应该能够使用AVG() 而不是SUM() / COUNT()

    【讨论】:

    • @Francesco:抱歉,我需要使用 HAVING 而不是 WHERE 子句 - 我更新了答案
    • @Francesco 当然,你想按什么排序?只需将ORDER BY 放在HAVING 之后即可
    【解决方案2】:

    你可以使用HAVING子句:

    SELECT 
      `e`.*, 
      `rt`.`review_id`, 
      (SUM(vt.percent) / COUNT(vt.percent)) AS rating 
    FROM `catalog_product_entity` AS `e` 
    INNER JOIN `rating_option_vote` AS `vt`
      ON vt.review_id = e.review_id 
    GROUP BY `vt`.`review_id` 
    HAVING rating >= 0;
    

    由于您的问题被标记为 MySQL,因此该解决方案应该可以工作,如文档所示:

    ...在标准 SQL 中,包含 GROUP BY 子句的查询不能引用 HAVING 子句中未在 GROUP BY 子句中命名的非聚合列。 MySQL 扩展允许引用此类列以简化计算。 ...

    官方 MySQL 编译默认启用此扩展。

    参考:http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html(在页面上第一次出现 HAVING 一词时)

    【讨论】:

    • 但是您是否还遇到rating 是无效标识符的问题?
    • 从 MySQL 开始,HAVING 子句按预期适用于这种情况。我刚刚发现在标准 SQL 中,HAVING 子句必须引用 GROUP BY 中的某个命名列。我不知道在这种情况下其他 RDBMS 是否像 MySQL 一样工作......
    • 知道了,没有注意到 MySQL 部分(嘿,我学到了一些东西 :) 顺便说一句,如果你好奇,它在 Oracle 中不起作用)
    • 有趣,我也不知道 MySQL。
    • @user1766760 你没有错过标签,MySQL 最初并不存在。一旦我看到 OP 在我的初始答案中发布的错误号,我就添加了它。
    【解决方案3】:

    聚合函数过滤时需要使用HAVING子句:

    SELECT 
      # `e`.*, => is this needed
      `rt`.`review_id`, 
      (SUM(vt.percent) / COUNT(vt.percent)) AS rating 
      AVG(vt.percent) AS rating1 # same as above 
    FROM `catalog_product_entity` AS `e` 
    INNER JOIN `rating_option_vote` AS `vt`
      ON vt.review_id = e.review_id 
    GROUP BY `vt`.`review_id`
    HAVING AVG(vt.percent) > 0
    

    另外两点:

    1) SUM(x)/COUNT(x) AVG(x)

    2) 您将 e.* 包含在 select 中,但未包含在 group by 中。 MySql 允许您这样做,但其他数据库不会。

    【讨论】:

      【解决方案4】:

      使用HAVING 表示聚合条件(例如您拥有的条件)

      SELECT `e`.*, `rt`.`review_id`, (SUM(vt.percent) / COUNT(vt.percent)) AS rating 
      FROM `catalog_product_entity` AS `e` 
      INNER JOIN `rating_option_vote` AS `vt`
          ON vt.review_id = e.review_id 
      WHERE ( rating >= '0') 
      GROUP BY `vt`.`review_id'
      HAVING (SUM(vt.percent) / COUNT(vt.percent)) > 0
      

      【讨论】:

        猜你喜欢
        • 2021-06-01
        • 1970-01-01
        • 2020-03-16
        • 2014-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多