具有别名和聚合函数的MySQL查询问题

时间:2010-09-03 22:02:34

标签: mysql aggregate-functions mysql-error-1111

我有一个麻烦的MySQL查询如下:

SELECT camera_id, ((avg(low_price) + avg(high_price)) / 2) as avg_price
FROM camera_general, camera_products
WHERE camera_id = ir_camera_id
AND dp_post_dt IS NOT NULL
AND dp_post_dt NOT LIKE '0000%'
AND currently_manufactured = 'Yes'
AND ((no_of_sellers >= 0) OR ((TO_DAYS(CURRENT_DATE) - TO_DAYS(dp_post_dt)) < 120))
AND avg_price < 150 
AND camera_id != 1411
AND camera_id != 9
ORDER BY rand();

这个在'where子句'中产生了“未知列'avg_price'”错误。我理解这是因为WHERE子句中不允许使用列别名。 (请纠正我,如果我出错的话,请。)

所以,我调整了这样的查询:

SELECT camera_id, ((avg(low_price) + avg(high_price)) / 2) as avg_price
FROM camera_general, camera_products
WHERE camera_id = ir_camera_id
AND dp_post_dt IS NOT NULL
AND dp_post_dt NOT LIKE '0000%'
AND currently_manufactured = 'Yes'
AND ((no_of_sellers >= 0) OR ((TO_DAYS(CURRENT_DATE) - TO_DAYS(dp_post_dt)) < 120))
AND ((avg(low_price) + avg(high_price)) / 2) < 150 
AND camera_id != 1411
AND camera_id != 9
ORDER BY rand();

使用实际计算替换别名,此查询产生错误:“无效使用组函数”。我理解这是因为直到WHERE子句完成处理之后才能发生avg()。

然后我尝试了:

SELECT camera_id, ((avg(low_price) + avg(high_price)) / 2) as avg_price
FROM camera_general, camera_products
ORDER BY rand();
HAVING camera_id = ir_camera_id
AND dp_post_dt IS NOT NULL
AND dp_post_dt NOT LIKE '0000%'
AND currently_manufactured = 'Yes'
AND ((no_of_sellers >= 0) OR ((TO_DAYS(CURRENT_DATE) - TO_DAYS(dp_post_dt)) < 120))
AND avg_price < 150 
AND camera_id != 1411
AND camera_id != 9;

用HAVING替换WHERE并且它产生了这个错误“你的SQL语法有错误;请检查与你的MySQL服务器版本相对应的手册,以便在'HAVING camera_id = ir_camera_id'附近使用正确的语法。” / p>

在这一点上,我觉得我在黑暗中试图让这个查询起作用。有人会指导我朝着正确的方向努力使这个问题成为一个有效的查询吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

  1. 即使您可以使用WHERE指定连接条件,最好还是使用LEFT[INNER] JOIN子句。
  2. 如果您要按非汇总字段进行过滤,请将过滤条件放入WHERE,如果您需要按汇总进行过滤,请将条件移至HAVING
  3. 在同一查询中使用聚合和非聚合时,请不要忘记GROUP BY

    SELECT camera_id, ((avg(low_price) + avg(high_price)) / 2) as avg_price FROM camera_general
    INNER JOIN camera_products ON (camera_id = ir_camera_id)
    WHERE dp_post_dt IS NOT NULL
    AND dp_post_dt NOT LIKE '0000%'
    AND currently_manufactured = 'Yes'
    AND ((no_of_sellers >= 0) OR ((TO_DAYS(CURRENT_DATE) - TO_DAYS(dp_post_dt)) < 120))
    AND camera_id != 1411 AND camera_id != 9
    GROUP BY camera_id
    HAVING avg_price < 150
    ORDER BY rand();

答案 1 :(得分:1)

ORDER子句应该在HAVING子句之后。 (除了你在;之后添加分号ORDER BY rand()然后继续HAVING,这实际上是另一个查询的开始,因为第一个以;结束。 / p>