Проблема MySQL Query с псевдонимами и агрегатными функциями - PullRequest
2 голосов
/ 04 сентября 2010

У меня сложный запрос 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();

Эта ошибка вызвала ошибку «Неизвестный столбец 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;

Замена WHERE на HAVING, и он выдает эту ошибку "У вас есть ошибка в вашем синтаксисе SQL; проверьте правильность синтаксиса в руководстве, соответствующем вашей версии сервера MySQL, рядом с 'HAVING camera_id = ir_camera_id'".

И в этот момент я чувствую, что стреляю в темноте, пытаясь заставить этот запрос работать. Может ли кто-нибудь направить меня в правильном направлении, чтобы сделать этот функциональный запрос?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 04 сентября 2010
  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<br> INNER JOIN camera_products ON (camera_id = ir_camera_id)<br> WHERE dp_post_dt IS NOT NULL<br> AND dp_post_dt NOT LIKE '0000%'<br> AND currently_manufactured = 'Yes'<br> AND ((no_of_sellers >= 0) OR ((TO_DAYS(CURRENT_DATE) - TO_DAYS(dp_post_dt)) < 120))<br> AND camera_id != 1411 AND camera_id != 9<br> GROUP BY camera_id<br> HAVING avg_price < 150<br> ORDER BY rand();

1 голос
/ 04 сентября 2010
Предложение

ORDER должно идти после предложения HAVING.(кроме того, вы ставите точку с запятой ; после ORDER BY rand(), затем продолжаете с HAVING, что на самом деле является началом другого запроса, поскольку первый завершился на ;).

...