SQL - SUM()的WHERE条件

4

是否可以像这样做:

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条件。

4个回答

7
这可以通过使用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子句 - 我更新了我的答案。 - Adam Wenger
@Francesco 当然可以,您想按什么排序?只需在 HAVING 后面加上您的 ORDER BY 即可。 - Adam Wenger

3
您可以使用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 子句的查询不能引用未在 GROUP BY 子句中命名的 HAVING 子句中的非聚合列。MySQL 扩展允许引用这些列以简化计算。
此扩展在官方 MySQL 编译中默认启用。
参考文献:http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html(在页面上第一次出现单词 HAVING 时)。

1
但是你还是遇到了“rating”无效标识符的问题,对吧? - user1766760
1
在MySQL中,HAVING子句按预期适用于此情况。我刚发现在标准SQL中,HAVING子句必须引用GROUP BY中的某个命名列。我不知道其他RDBMS在这种情况下是否像MySQL一样工作... - Felypp Oliveira
注意了,没注意到那个MySQL部分(嘿我学到了东西 :) 顺便说一句,如果你*有兴趣的话,它在Oracle中不起作用) - user1766760
有趣的是,我也不知道MySQL的这一点。 - Adam Wenger
@user1766760,你没有错过标签,最初没有MySQL。当我看到OP发布的错误编号后,我在我的初始答案中添加了它。 - Adam Wenger
@user1766760 是的,我也很好奇...哈哈!知道了真好!在某些情况下,我喜欢这样做,因为我只使用MySQL。这个扩展也可以被禁用,所以我的解决方案将不起作用...=Z - Felypp Oliveira

1

当使用聚合函数进行过滤时,您需要使用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.*但不在分组中。 MySql允许您这样做,但其他数据库不允许。


0

使用 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接