您没有说明您正在使用什么 SQL 引擎 - 它可以有所作为。
我提供了一个需要支持 row_number() 函数的解决方案。我相信至少 Oracle、DB2 和 SQLServer 都支持 row_number()。
一旦将表一中的不同值转换为单行,问题就相当简单了。如果表一中存在超过 4 个不同的值,则不能有任何匹配项。似乎应该有更好的方法来进行旋转,但我知道这个解决方案有效。
如果一个为空,我已经努力确保答案返回两个中的所有行,并且忽略一个中的重复行。
with
uniqueOne as (
select distinct col1 from one
),
ranked as (
select col1, row_number() over (order by col1) seq from uniqueOne
),
vals as (
select t1.col1 val1,
t2.col1 val2,
t3.col1 val3,
t4.col1 val4
from (select 1 dummy) dummy
left join ranked t1 on t1.seq=1
left join ranked t2 on t2.seq=2
left join ranked t3 on t3.seq=3
left join ranked t4 on t4.seq=4
left join ranked t5 on t5.seq=5
where t5.seq is null
)
select two.*
from two
cross join vals
where (vals.val1 is null or vals.val1 in (two.col1, two.col2, two.col3, two.col4))
and (vals.val2 is null or vals.val2 in (two.col1, two.col2, two.col3, two.col4))
and (vals.val3 is null or vals.val3 in (two.col1, two.col2, two.col3, two.col4))
and (vals.val4 is null or vals.val4 in (two.col1, two.col2, two.col3, two.col4))
;
这是解决方案的现场演示
天哪,我想我应该阅读自己的答案并更频繁地进行一些研究。SQLServer 有一个 Pivot 运算符,使解决方案非常高效。Oracle 也有 Pivot,但它使用不同的语法。
这是SQLServer Pivot 解决方案的工作演示。看看甜蜜的执行计划。
这是 SQLServer 查询:
with
uniqueOne as (
select distinct col1 from one
),
ranked as (
select col1, row_number() over (order by col1) seq from uniqueOne
),
vals as (
select [1] val1, [2] val2, [3] val3, [4] val4, [5] val5
from ranked
pivot ( min(col1) for seq in ([1],[2],[3],[4],[5]) ) PivotTable
)
select two.*
from two
join vals on val5 is null
where (vals.val1 is null or vals.val1 in (two.col1, two.col2, two.col3, two.col4))
and (vals.val2 is null or vals.val2 in (two.col1, two.col2, two.col3, two.col4))
and (vals.val3 is null or vals.val3 in (two.col1, two.col2, two.col3, two.col4))
and (vals.val4 is null or vals.val4 in (two.col1, two.col2, two.col3, two.col4))
;