在我们加入两个表table_A和table_B时是否有一种方法在SQL中,如果我们无法匹配条件上的两个表,则说我们会尝试第二个条件criteria_Y
这样的事情:
select *
from table_A, table_B
where table_A.id = table_B.id2
and (if there is no row where table_B.criteria_X = X then try table_B.criteria_Y = Y)
以下查询不是解决方案:
..
and (table_B.criteria_X = X OR table_B.criteria_Y = Y)
由于
答案 0 :(得分:0)
这是找到最佳匹配查询:
select *
from
(
select *,
row_number() -- based on priority, #1 criteria_X, #2 criteria_Y
over (partition by table_A.id
order by case when table_B.criteria_X = X then 1
else 2
end) as best_match
from table_A, table_B
where table_A.id = table_B.id2
and (table_B.criteria_X = X OR table_B.criteria_Y = Y)
) dt
where best_match = 1
如果OR
条件导致索引访问权限丢失,您可以尝试将其拆分为两个UNION ALL
选项。
答案 1 :(得分:0)
典型方法使用left join
两次。 。 。每个标准一次。然后在coalesce()
中使用select
。并且,使用连接键上的索引,这也应该具有非常好的性能:
select a.*, coalesce(b1.colx, b2.colx)
from table_A a left join
table_B b1
on a.id = b1.id2 and b1.criteria_X = X left join
table_B b2
on a.id = b1.id2 and b2.criteria_Y = Y
where b1.id2 is not null or b2.id2 is not null;
where
子句确保至少有一行匹配。
这在所有情况下都不起作用 - 特别是,每个连接只需要返回0或1个匹配的行。这通常是这种“优先”连接的情况。
替代版本使用row_number()
。这类似于@dnoeth的方法,但行号计算在连接之前完成:
select a.*, coalesce(b1.colx, b2.colx)
from table_A a join
(select b.*,
row_number() over (partition by id2
order by (case when criteria_x = X then 1
when criteria_y = Y then 2
end)
) as seqnum
from table_B b
where criteria_x = X or criteria_y = Y
) b
on a.id = b.id2 and seqnum = 1