MySQL 5.6:多个左连接导致错误填充列

时间:2015-11-03 10:45:42

标签: mysql sql

SQLFiddle:http://sqlfiddle.com/#!9/9d5b2

我在MYSQL 5.6下面有以下表格:

users
id | name
---------
1  | John


groups
id | name
---------
1  | admin


constaints
id | name
------------
1  | cons1
2  | cons2


user_to_group
userid | groupid
----------------
1      | 1

constraint_to_group
constrainid | groupid
----------------------
1           | 1

constraint_to_user
constrainid | userid
----------------------
2           | 1

这个想法是:

  • 我有群组有约束。
  • 用户可以是成员或0..n 群组
  • 约束也可以直接关联到用户

我正在尝试为特定用户构建一个返回的查询

  • 所有
  • 中的约束
  • 与他直接相关的约束

我做了以下事情:

SELECT  `users`.*, 
        `constraints`.id as cons_id,
        `constraints`.name as cons_name,
        `groups`.id as group_id,
        `groups`.name as group_name 
FROM `users` 
    LEFT JOIN `user_to_group` 
        ON `user_to_group`.userid=`users`.id 
    LEFT JOIN `groups` 
        ON `groups`.id=`user_to_group`.groupid 
    LEFT JOIN `constraint_to_group` 
        ON `constraint_to_group`.groupid=`user_to_group`.groupid 
    LEFT JOIN `constraint_to_user`
        ON `constraint_to_user`.userid=`users`.id
    LEFT JOIN `constraints` 
        ON (`constraints`.id=`constraint_to_group`.constraintid OR `constraints`.id=`constraint_to_user`.constraintid) 
WHERE `users`.id=1

这让我:

|id| name |cons_id|cons_name|group_id|group_name
------------------------------------------------
|1 | john |1      |cons1    |1       |admin
|1 | john |2      |cons2    |1       |admin

我的问题:

cons2 并非来自 admin 组,它直接与用户相关联,因此我想要 group_id group_name 设置为NULL(或其他),以便我知道约束是来自一个组还是直接与用户相关联

3 个答案:

答案 0 :(得分:1)

您可以在constraint_to_group.constraintidconstraints.id之间进行比较。

所以,而不是:

    `groups`.id as group_id,
    `groups`.name as group_name

使用:

    IF(`constraint_to_group`.constraintid = `constraints`.id, 
       `groups`.id, NULL) as group_id,
    IF(`constraint_to_group`.constraintid = `constraints`.id, 
        `groups`.name, NULL) as group_name

SELECT子句中。

Demo here

答案 1 :(得分:0)

您无法将它们设置为NULL。但是如果你想获得cons_name的所有值,你可以使用GROUP_CONCAT函数。

SELECT  `users`.*, 
        `constraints`.id as cons_id,
        GROUP_CONCAT(`constraints`.name) as cons_name,
        `groups`.id as group_id,
        `groups`.name as group_name 
FROM `users` 
    LEFT JOIN `user_to_group` 
        ON `user_to_group`.userid=`users`.id 
    LEFT JOIN `groups` 
        ON `groups`.id=`user_to_group`.groupid 
    LEFT JOIN `constraint_to_group` 
        ON `constraint_to_group`.groupid=`user_to_group`.groupid 
    LEFT JOIN `constraint_to_user`
        ON `constraint_to_user`.userid=`users`.id
    LEFT JOIN `constraints` 
        ON (`constraints`.id=`constraint_to_group`.constraintid OR `constraints`.id=`constraint_to_user`.constraintid) 
WHERE `users`.id=1
GROUP BY users.id

答案 2 :(得分:0)

认为我会将其拆分为2个联合查询。没有做太多的检查,这样的事情: -

SELECT  users.id, 
        users.name,
        constraints.id as cons_id,
        constraints.name as cons_name,
        groups.id as group_id,
        groups.name as group_name 
FROM users 
LEFT JOIN user_to_group ON user_to_group.userid = users.id 
LEFT JOIN groups ON groups.id = user_to_group.groupid 
LEFT JOIN constraint_to_group ON constraint_to_group.groupid = user_to_group.groupid 
LEFT JOIN constraints ON constraints.id = constraint_to_group.constraintid
WHERE users.id=1
UNION 
SELECT  users.id, 
        users.name,
        constraints.id as cons_id,
        constraints.name as cons_name,
        NULL as group_id,
        NULL as group_name 
FROM users 
LEFT JOIN constraint_to_user ON constraint_to_user.userid = users.id
LEFT JOIN constraints ON constraints.id = constraint_to_user.constraintid
WHERE users.id=1