mysql在条件下连接2个表,保留一些值

时间:2014-09-25 13:45:53

标签: mysql jointable

我有2张桌子。

users(id,username)links(id,usernameORid)

行示例: users{ [1,test] , [2,stack] }links{ [1,overflow] , [2, 1] }

因此,表links可能包含表users中的用户名或ID。正如您在示例中看到的, 来自usernameORid的{​​{1}}可能不包含来自用户的linksid。 我希望你理解我的榜样。

现在,我有这个问题:

username

但如果SELECT l.usernameORid, u.username, u.id FROM links l LEFT JOIN users u ON l.usernameORid= u.id LEFT JOIN user_roles ur ON ur.userID = u.id WHERE ur.roleID < 4 group by u.id 不是来自links的实际usernameORidusername,则此查询不会返回id的行。

在上一个示例中,不会返回行users。我也想要这一行。

我如何实现这一目标?

编辑: 问题与

部分相关
[1,overflow]

但是,我怎么能实现呢?

LEFT JOIN user_roles ur ON ur.userID = u.id WHERE ur.roleID < 4

2 个答案:

答案 0 :(得分:1)

将您的最终WHERE条件更改为:

WHERE ur.roleID < 4 OR u.id IS NULL

这将允许它返回users中没有匹配的行。通常情况下,LEFT JOIN会自行执行此操作,但由于您在该表上执行了其他连接,因此WHERE子句会将这些不匹配的行过滤掉,因为它们没有roleID

答案 1 :(得分:0)

您可以在linksusers之间的联接中使用OR语句。这样,您就可以选择users等于link.usernameORidusers.id

users.username条记录
SELECT l.usernameORid,
    u.username,
    u.id
FROM links l
LEFT JOIN users u ON 
    l.usernameORid = u.id OR
    lusernameORid = u.username
LEFT JOIN user_roles ur
    ON ur.userID = u.id
WHERE ur.roleID < 4
GROUP BY u.id

如果找到的users->user_roles.roleID小于4,这仍然会导致记录丢失。如果您想要保留链接记录,无论是否通过用户名或ID找到用户,那么您需要查询子查询usersuser_roles表加入并在那里应用您的WHERE语句。此查询如下:

SELECT  
     l.usernameORid,
     u.username,
     u.id
FROM links l
LEFT JOIN 
    (   
        SELECT
            users.username,
            users.idusers
        FROM
            users
            LEFT JOIN user_roles ON
                user_roles.userID = users.id
        WHERE 
            user_roles.roleID < 4
    ) u ON
        l.usernameORid= u.id OR
        l.usernameORid = u.username
group by u.id

此外,如果您希望当users表缺少匹配时,您的返回的第2列或第3列保留l.usernameorid中的值...如果您的users.id始终为数字你可以用CASE语句做一些诡计:

SELECT  
    l.usernameORid,
    Coalesce(u.username, CASE WHEN .lusernameORid REGEXP '^[0-9]+$' THEN NULL ELSE l.usernameORid END) as username,
    Coalesce(u.username, CASE WHEN .lusernameORid REGEXP '^[0-9]+$' THEN l.usernameORid ELSE NULL END) as userid
FROM links l
LEFT JOIN 
    (   
        SELECT
            users.username,
            users.idusers
        FROM
            users
            LEFT JOIN user_roles ON
                user_roles.userID = users.id
        WHERE 
            user_roles.roleID < 4
    ) u ON
        l.usernameORid= u.id OR
        l.usernameORid = u.username
group by u.id

请记住,如果users表与links.usernameORid没有匹配,则只能确定用户名或ID,因此您将在其中一个中使用NULL这两个领域。