使用具有多个 ON 的连接子句组合来自多个表的值
Combining values from multiple tables using join clause with multiple ON
我想使用 LEFT JOIN 子句合并所有相关数据,但如果 table 之一没有来自其他 table 的匹配记录,它将不会显示。你能检查我的查询吗,它似乎丢失或完全搞砸了。这是我的查询。
SELECT*
FROM
MASTER_TBL
LEFT JOIN
(
SELECT*
FROM
TBLA A
LEFT JOIN
TBLB B
ON
A.ID=B.ID AND A.DESC=B.DESC
LEFT JOIN
TBLC C
ON
B.ID=C.ID AND B.DESC=C.DESC
LEFT JOIN
TBLD D
ON
C.ID=D.ID AND C.DESC=D.DESC
) E
ON
MASTER_TBL.ID=E.ID
问题是您正在跨联接级联条件。例如,这里是 table d
的连接条件:
C.ID = D.ID AND C.DESC = D.DESC
要匹配,您需要在 C
中已有匹配行。
根据您的查询,您似乎可以使用大师 table 的 id
来搜索以下所有 table。至于 desc
列,看起来你最好的选择是使用 table a
.
所以,考虑一下:
select *
from master_tbl m
left join tbla a on a.id = m.id
left join tblb b on b.id = m.id and b.desc = a.desc
left join tblc c on c.id = m.id and c.desc = a.desc
left join tbld d on d.id = m.id and d.desc = a.desc
如果 desc
在 tablea
中不可用,我们可以切换到 full join
。逻辑比较复杂,但看起来像:
select *
from master_tbl m
full join tbla a on a.id = m.id
full join tblb b on b.id = m.id and b.desc = a.desc
full join tblc c on c.id = m.id and c.desc = coalesce(a.desc, b.desc)
full join tbld d on d.id = m.id and d.desc = coalesce(a.desc, b.desc, c.desc)
这种方法使用UNION ALL
将名为tables(tbla、tblb、tblc、tbld)的字母组合成一个CTE
,常见的table表达式。然后通过 id、[desc] 和跨登录列的交叉制表(或旋转)汇总组合的 table。然后将旋转的结果 LEFT JOIN
'ed 到 master_tbl。像这样。
with
tbl_cte(tbl, id, [login], [desc]) as (
select 'A', * from tbla
union all
select 'B', * from tblb
union all
select 'C', * from tblc
union all
select 'D', * from tblc),
pvt_cte(id, tbla_login, tblb_login, tblc_login, tbld_login, [desc]) as (
select id,
max(case when tbl='A' then [login] else null end) as tbla_login,
max(case when tbl='B' then [login] else null end) as tblb_login,
max(case when tbl='C' then [login] else null end) as tblc_login,
max(case when tbl='D' then [login] else null end) as tbld_login,
[desc]
from tbl_cte
group by id, [desc])
select mt.id, [name], country, [status], pc.tbla_login,
pc.tblb_login, pc.tblc_login, pc.tbld_login, pc.[desc]
from master_tbl mt
left join pvt_cte pc on mt.id=pc.id;
我想使用 LEFT JOIN 子句合并所有相关数据,但如果 table 之一没有来自其他 table 的匹配记录,它将不会显示。你能检查我的查询吗,它似乎丢失或完全搞砸了。这是我的查询。
SELECT*
FROM
MASTER_TBL
LEFT JOIN
(
SELECT*
FROM
TBLA A
LEFT JOIN
TBLB B
ON
A.ID=B.ID AND A.DESC=B.DESC
LEFT JOIN
TBLC C
ON
B.ID=C.ID AND B.DESC=C.DESC
LEFT JOIN
TBLD D
ON
C.ID=D.ID AND C.DESC=D.DESC
) E
ON
MASTER_TBL.ID=E.ID
问题是您正在跨联接级联条件。例如,这里是 table d
的连接条件:
C.ID = D.ID AND C.DESC = D.DESC
要匹配,您需要在 C
中已有匹配行。
根据您的查询,您似乎可以使用大师 table 的 id
来搜索以下所有 table。至于 desc
列,看起来你最好的选择是使用 table a
.
所以,考虑一下:
select *
from master_tbl m
left join tbla a on a.id = m.id
left join tblb b on b.id = m.id and b.desc = a.desc
left join tblc c on c.id = m.id and c.desc = a.desc
left join tbld d on d.id = m.id and d.desc = a.desc
如果 desc
在 tablea
中不可用,我们可以切换到 full join
。逻辑比较复杂,但看起来像:
select *
from master_tbl m
full join tbla a on a.id = m.id
full join tblb b on b.id = m.id and b.desc = a.desc
full join tblc c on c.id = m.id and c.desc = coalesce(a.desc, b.desc)
full join tbld d on d.id = m.id and d.desc = coalesce(a.desc, b.desc, c.desc)
这种方法使用UNION ALL
将名为tables(tbla、tblb、tblc、tbld)的字母组合成一个CTE
,常见的table表达式。然后通过 id、[desc] 和跨登录列的交叉制表(或旋转)汇总组合的 table。然后将旋转的结果 LEFT JOIN
'ed 到 master_tbl。像这样。
with
tbl_cte(tbl, id, [login], [desc]) as (
select 'A', * from tbla
union all
select 'B', * from tblb
union all
select 'C', * from tblc
union all
select 'D', * from tblc),
pvt_cte(id, tbla_login, tblb_login, tblc_login, tbld_login, [desc]) as (
select id,
max(case when tbl='A' then [login] else null end) as tbla_login,
max(case when tbl='B' then [login] else null end) as tblb_login,
max(case when tbl='C' then [login] else null end) as tblc_login,
max(case when tbl='D' then [login] else null end) as tbld_login,
[desc]
from tbl_cte
group by id, [desc])
select mt.id, [name], country, [status], pc.tbla_login,
pc.tblb_login, pc.tblc_login, pc.tbld_login, pc.[desc]
from master_tbl mt
left join pvt_cte pc on mt.id=pc.id;