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 首先留下你想用WHEREcalsue做什么的问题...... @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 查询

Hibernate Criteria:在 Subquery/DetachedCriteria 中执行 JOIN

将这些 DB2 SUBQUERY 重写为 Join

Clickhouse解决No alias for subquery or table function in JOIN