English version of this post available here
MySQL někdy dokáže překvapit. Teď jsem například narazil na toto: Mám tento SQL dotaz:
SELECT id, username, locked, c.*,
(SELECT COUNT(*)
FROM web_login_users
WHERE user=id AND (NOW()-last_action)<600) AS login_count
FROM web_users
LEFT JOIN web_user_information AS c ON (id=user)
Ten bez problému funguje a jako jeden ze sloupců se vrátí sloupec login_count. Chtěl jsem vybrat pouze řádky, kde je login_count větší než jedna. Intuitivně jsem zkusil toto:
SELECT id, username, locked, c.*,
(SELECT COUNT(*)
FROM web_login_users
WHERE user=id AND (NOW()-last_action)<600) as login_count
FROM web_users
LEFT JOIN web_user_information AS c ON (id=user)
WHERE login_count > 1
To ale nefunguje. MySQL hlásí, že nezná sloupec login_count.
Zajímavé je, že toto funguje:
SELECT id, username, locked, c.*,
(SELECT COUNT(*) FROM web_login_users
WHERE user=id AND (NOW()-last_action)<600) AS login_count
FROM web_users
LEFT JOIN web_user_information AS c ON (id=user)
ORDER BY login_count
Po několika pokusech a konzultaci s kamarádem se vzdávám.
Pokus s JOIN
SELECT id, username, locked, c.*,
COUNT(login_users.user) AS login_count
FROM web_users
LEFT JOIN web_user_information AS c ON (id=user)
LEFT OUTER JOIN web_login_users AS login_users
ON (user=id AND (NOW()-last_action)<600)
WHERE login_count > 0
končí stejnou hláškou jako předešlé (Unknown column ‚login_count‘ in ‚where clause‘).
Toto se mi sice nelíbí, ale alespoň to funguje:
SELECT id, username, locked, c.*,
(SELECT COUNT(*) FROM web_login_users WHERE
user=id AND (NOW()-last_action)<600) AS login_count
FROM web_users LEFT JOIN web_user_information AS c ON (id=user)
WHERE (SELECT COUNT(*) FROM web_login_users
WHERE user=id AND (NOW()-last_action)<600) > 0
Tags: MySQL, programování
Zkus výstup seskupit pomocí „group by“ a podmínky pro skupiny pak nejsou pomocí „where“, ale „having“.
Děkuji za radu. To opravdu funguje tak, jak jsem si původně představoval.
Teoreticky by přece GROUP BY ale nemělo být potřeba, když agregační funkce používám jenom ve vnořeném SELECTu a WHERE podmínkou omezuji pouze podle jednoho sloupce, ne?