Here is my SQL
'SELECT u.`id`,
u.`email`,
u.`password`,
u.`first_name`,
u.`last_name`,
u.`role_id`,
MAX( ul.`datetime` ) as `last_login`,
SUM( ul.`failed` ) as `failed_logins`
FROM `users` `u`
JOIN ( SELECT `user_id`, `datetime`, `failed`
FROM `user_logins`
ORDER BY `datetime` DESC
LIMIT ' . (int) $failedLoginThreshold . ' ) `ul`
ON ( u.`id` = ul.`user_id` )
WHERE u.`email` = ' . Database::instance()->escape($email) . '
AND u.`role_id` > 0
GROUP BY u.`id`'
Using the information gathered, I can decide whether to log the user in, kick them as having a wrong password, or lock them out if they have attempted to login too many times incorrectly.
I just noticed when I DROP‘d the table, none of the logins worked, because the subquery would return 0 rows.
SQL always gets me. How can I change this query so in the event of a user having never logged in before, it will allow them?
Of course I could enter a bogus row for every user, but it sounds too hacky for me (and prone to breakage).
Thanks for reading.
Turn your
JOINinto aLEFT JOIN. AJOINdefaults toINNER JOIN, which will not return a record unless a match was able to be made in the other table. Switching toLEFT JOINtells MySQL to return records from the “left” table (i.e. youruserstable) even if there’s no matching record in the “right” table (youruser_loginstable).