使用联合表代替交集

3

我有以下结构

user
id | name
----------
1  | Foo
2  | Bar

profile
id | name      | user_id
--------------------------
1  | Profile 1 | 1
2  | Profile 2 | 2

profile_access
id | user_id | profile_id
--------------------------
1  | 2       | 1

期望从查询中获得以下结果

id | name      | user_id
-----------------------------------
1  | Profile 1 | 1
2  | Profile 2 | 2
1  | Profile 1 | 2

但我不知道如何“合并”这些表格。我尝试过:
SELECT profile.*
FROM profile profile
LEFT JOIN profile_access AS profile_access
ON (
   profile_access.profile_id = profile.id
)

这个返回值

id | name      | user_id
-----------------------------------
1  | Profile 1 | 1
2  | Profile 2 | 2

并且
SELECT profile.*
FROM profile profile
RIGHT JOIN profile_access AS profile_access
ON (
   profile_access.profile_id = profile.id
)

哪些结果

id | name      | user_id
-----------------------------------
2  | Profile 1 | 2

什么是正确的查询方式?我是否在使用联接方面有误或者期望这些表格的结果是不可能的?
编辑: 预期的结果应该是:
id | name      | user_id
-----------------------------------
1  | Profile 1 | 1
2  | Profile 2 | 2
1  | Profile 1 | 2

1
你确定这是你期望的输出吗?再检查一下ID。 - Mosty Mostacho
抱歉,问题已更新。 - Gabriel Santos
1个回答

2

目前不清楚您需要的确切逻辑是什么,但以下内容将返回问题中的结果:

select p.id, p.name, p.user_id
from profile p
union all
select p.id, p.name, pa.user_id
from profile p join
     profile_access pa
     on pa.profile_id = p.id;

编辑:

这将返回:

id | name      | user_id
-----------------------------------
1  | Profile 1 | 1
2  | Profile 2 | 2
1  | Profile 1 | 2

请注意,最后一行的id为1而不是原始预期答案中的2。对我来说这很合理,因为表中id=1仅与'Profile 1'的个人资料名称相关联。但是,要获得实际输出,请执行以下操作:
select p.id, p.name, p.user_id
from profile p
union all
select pa.profile_id, p.name, pa.user_id
from profile p join
     profile_access pa
     on pa.user_id = p.user_id;

我选择第一种解决方案的原因是,示例查询都是在profile_id字段上连接profileprofile_access,而不是在user_id字段上连接。


2
这是 SQLFiddle,因为我正在处理同样的事情 http://sqlfiddle.com/#!2/18ea8/3 - Michael Berkowski
1
实际上,这是不正确的。您可以看到结果与预期输出不匹配。我认为这是问题中的错误。 - Mosty Mostacho
而你的答案是 ;D - Gabriel Santos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接