LEFT JOIN 和 SUBQUERY 与空列 / null 作为结果
Posted
技术标签:
【中文标题】LEFT JOIN 和 SUBQUERY 与空列 / null 作为结果【英文标题】:LEFT JOIN & SUBQUERY with empty columns / null as result 【发布时间】:2021-01-02 18:51:26 【问题描述】:我正在尝试加入两个表。一个用户表(包括用户 ID、用户名、电子邮件、密码等)和一个登录表,其中包含一个用户 ID 和一个时间戳。结果,我想要了解所有用户的最后一次登录(只有每个用户的最近一次登录)。如果用户从未登录过,则结果应该为空。
到目前为止,我的查询如下所示:
SELECT
user.id,
user.username,
DATE_FORMAT(user_login.time, "%d.%m.%Y %H:%i")
FROM
user
LEFT JOIN
user_login
ON
(user.id=user_login.user_id)
WHERE
user_login.id=(
SELECT
id
FROM
user_login
WHERE
user_id=user.id
ORDER BY
id DESC
LIMIT 1);
它提供最近登录的用户作为结果,但只提供至少有一次登录的用户,因此 user_login 表中至少有一个数据集。对于每个从未登录过的用户,我只想得到 null 作为结果。
我已经找到了解决方案,但我在其中使用“1=1”作为 WHERE 子句,这对我来说似乎真的不专业。查询如下所示:
SELECT
user.id,
user.username,
DATE_FORMAT(user_login.time, "%d.%m.%Y %H:%i")
FROM
user
LEFT JOIN
user_login
ON
(user.id=user_login.user_id)
WHERE
(user_login.id=(
SELECT
id
FROM
user_login
WHERE
user_id=user.id
ORDER BY
id DESC
LIMIT 1)
OR 1=1)
GROUP BY
user.id;
有没有人有更好的解决这个问题的方法?
非常感谢您的帮助!
【问题讨论】:
更好的解决方案是删除完整的WHERE
子句。对于未登录的用户,user_login
表中的值将是 NULL
。
首先留下你想用WHERE
calsue做什么的问题......
@Luuk本例中的where子句用于获取最高登录id,可能是用户最后一次登录(可以有多个属于一个用户)
@Remy:我会使用 MAX(user_login.time)
来实现这一点......
@Luuk 谢谢!这就是我寻找的! :) 唯一奇怪的是,当我添加“ORDER BY user_login.time DESC”时,它会显示我从 12 月开始登录,然后再从本月开始登录。但目前这并不重要。
【参考方案1】:
我会建议窗口函数:
SELECT u.id, u.username,
DATE_FORMAT(ul.time, '%d.%m.%Y %H:%i')
FROM user u LEFT JOIN
(SELECT ul.*,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY time DESC) as seqnum
FROM user_login ul
) ul
ON u.id = ul.user_id AND seqnum = 1;
【讨论】:
以上是关于LEFT JOIN 和 SUBQUERY 与空列 / null 作为结果的主要内容,如果未能解决你的问题,请参考以下文章
MySQL LEFT JOIN 或 WHERE IN SUBQUERY
Mysql join with subquery join 使用相关名称
带有 CASE 和 JOIN SUBQUERY 的 Oracle SQL 查询