我正在尝试使用Postgres SQL进行案例联接,我希望在第一个匹配的案例后停止搜索
select *
from
table1 a
left join table2 b
on a.cond1 = b.cond1
and case when a.cond2 = b.cond2 and a.cond3 = b.cond3
then 1
when a.cond4 = b.cond4
then 1
else 0
end = 1
目的是如果cond2和cond3匹配到此为止,并仅使用table2中与其他匹配的行,则尝试对cond4进行匹配。但是结果是使行同时满足两个条件。我的SQL查询中有错误吗?
示例:
table1
id, cond1, cond2, cond3, cond4
1, 1, 1, 1, 1
2, 1, 0, 1, 1
3, 0, 1, 1, 0
4, 1, 1, 0, 0
table2
cond1, cond2, cond3, cond4, tag
1, 1, 1, 1, apple
1, 1, 0, 1, banana
结果
id, tag
1, apple
2, banana
3, null
4, null
但是我要加入 1,香蕉
答案 0 :(得分:0)
您可以尝试使用CTE
with cte as(
select count(case when a.cond2 = b.cond2 and a.cond3 = b.cond3 then 1 else 0 end)
checkcondition1,
count(case when a.cond4=b.cond4 then 1 else 0 end) checkcondition2
from table1 a
join table2 b on a.cond1 = b.cond1
)
select a.id, b.tag
from table1 a
left join table2 b
on a.cond1 = b.cond1
and case when (select count(*) from cte where checkcondition1>0)>0 and a.cond2 =
b.cond2 and a.cond3 = b.cond3
then 1
when (select count(*) from cte where checkcondition1=0 and
checkcondition1>0)>0 and a.cond4=b.cond4
then 1
else 0
end = 1
答案 1 :(得分:0)
我认为您想要一个lateral join
。如果a
中的每一行只有一个匹配行:
select *
from table1 a left join lateral
(select b.*
from table2 b
where a.cond1 = b.cond1 and
(a.cond2 = b.cond2 and a.cond3 = b.cond3 or
a.cond4 = b.cond4
)
order by (a.cond2 = b.cond2 and a.cond3 = b.cond3) desc
limit 1 desc
) b
on 1=1
否则,您可以将其表达为:
select *
from table1 a left join lateral
(select b.*,
rank() over (order by (a.cond2 = b.cond2 and a.cond3 = b.cond3) desc) as seqnum
from table2 b
where a.cond1 = b.cond1 and
(a.cond2 = b.cond2 and a.cond3 = b.cond3 or
a.cond4 = b.cond4
)
) b
on b.seqnum = 1;
答案 2 :(得分:0)
由于似乎您只希望找到第一场比赛,您可以使用:
select a.id,b.tag
from table1 a join table2 b on a.cond1 = b.cond1
where ( (a.cond2 = b.cond2 and a.cond3 = b.cond3)
or (a.cond4 = b.cond4)
)
order by a.id
limit 1;
关于表别名的简短说明(我的观点)。选择一个直观的价值。在这种情况下,t1和t2比a和b大得多。