3

首先,我什至不确定是否LEFT JOIN是做我想做的最好的方式,所以会尽力解释。

我有 2 个表 - 一个包含站点列表,另一个包含角色列表。一个用户可能只有一个角色,但他们可能拥有与站点一样多的角色。

表“网站”

site_id  |  site_name  | site_domain
---------------------------------------
1        |  Site A     | sitea.com
2        |  Site B     | siteb.com

表“角色”

site_id  |  user_id  | role_id
---------------------------------
1        |  1        | 1
1        |  2        | 1
2        |  2        | 2

如我上面的示例,用户 1 在一个站点上只有一个角色,但用户 2 在两个不同的站点上具有两个角色。

我想要做的,可能只是一个星期天晚上,而不是直截了当的事情,就是列出一个站点列表,以及每个用户的角色 - 如果用户的该站点不存在角色,然后返回 NULL(或 0)。

输出应如何产生的两个示例:

用户 1

site_id | site_name | site_domain | role_id
----------------------------------------------
1       | Site A    | sitea.com   | 1
2       | Site B    | siteb.com   | NULL

用户 2

site_id | site_name | site_domain | role_id
----------------------------------------------
1       | Site A    | sitea.com   | 1
2       | Site B    | siteb.com   | 2

我现在的查询如下,但是,第二个站点没有出现,因为用户没有定义角色(即像上面一样,但对于用户 1,第二个站点 B 不会列出)。我知道我只是错过了一些东西,但今晚想不起来:o(

SELECT site_id, site_name, site_domain, role_id 
FROM `sites` 
LEFT JOIN `roles` 
ON sites.site_id=roles.site_id 
WHERE roles.user_id='1'
4

1 回答 1

3

您需要做的是从一个包含所有站点和用户的表开始。然后加入roles表中的信息:

select s.site_id, s.site_name, s.site_domain, u.user_id, r.role_id
from (select distinct user_id from roles) u cross join
     sites s left outer join
     roles r
     on s.site_id = r.site_id and
        u.user_id = r.user_id

如果您有一个用户表,那么您可以用该表替换第一个子查询。

对于涉及单个用户的站点,您可以在子查询中放置一个常量:

select s.site_id, s.site_name, s.site_domain, u.user_id, r.role_id
from (select 1 as user_id) u cross join
     sites s left outer join
     roles r
     on s.site_id = r.site_id and
        u.user_id = r.user_id

where从句: where u.user_id = 1.

于 2013-03-03T20:24:43.073 回答