Mysterious MySQL
Česká verze tohoto zápisku dostupná zde
MySQL can be sometimes pretty surprising.
I have recently encountered this thing:
I have this SQL query:
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)
It works without any problems and the returned column set includes the column named login_count.
I wanted to get only the rows, where login_count is greater than 1. I intuitively tried this:
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
This does't work. MySQL complains about not knowing the login_count column. To make it more interesting, this will work as expected:
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
Having made some more attempts and consulted the problem with a friend, I give up.
This is the JOIN version that I quite expected to work:
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
It returns the same error as the previous attempts (Unknown column 'login_count' in 'where clause').
I don't quite like this version, but it functions well:
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
Labels: MySQL, Programming

