在第一个大小写匹配时未停止的Postgres SQL大小写联接

时间:2019-12-09 08:13:52

标签: sql postgresql join case

我正在尝试使用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,香蕉

3 个答案:

答案 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大得多。