2010-09-03 64 views
2

我有一個麻煩的MySQL查詢如下: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'附近使用的語法「。

在這一點上,我覺得我在黑暗中拍攝試圖使這個查詢工作。有人會指引我在正確的方向,使這是一個功能正常的查詢?

謝謝!

回答

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();

+0

謝謝 - 這工作。我明白(擡頭)#2和#3。但是,我仍然有點模糊,爲什麼最好做一個左[內]加入? – Yazmin 2010-09-08 12:16:42

+1

在'WHERE'中加入條件是舊的語法(ANSI SQL 1989)。它僅支持交叉和內連接(對於外連接,不同的服務器有不同的擴展名,例如TSQL具有'* ='AND'= *')。 'JOIN'關鍵字在SQL 1992中引入並支持外部連接。使用'JOIN'使得你的查詢變得清晰,並且在指定連接條件時使用它是一種很好的風格。 – a1ex07 2010-09-08 15:14:37

+0

謝謝。我很感謝解釋和幫助! – Yazmin 2010-09-09 13:10:22

1

ORDER條款應去HAVING條款。 (除了你在ORDER BY rand()之後加上分號;,然後繼續HAVING,這實際上是另一個查詢的開始,因爲第一個以;結束)。

+0

謝謝。分號與重新排列之前的所有內容混合在一起。但是,在HAVING之後移動ORDER子句確實解決了這個問題,但強制我將HAVING子句中使用的所有非聚合列添加到GROUP BY子句中。 – Yazmin 2010-09-08 12:12:25