2

我有一个麻烦的 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();

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

所以我尝试了:

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' 附近使用的正确语法”。

在这一点上,我觉得我在黑暗中射击,试图让这个查询工作。有人会引导我朝着正确的方向发展,以使其成为一个有效的查询吗?

谢谢!

4

2 回答 2

2
  1. 即使您可以使用WHERE指定连接条件,最好使用 inLEFT[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();

于 2010-09-03T22:23:00.600 回答
1

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

于 2010-09-03T22:04:53.480 回答