当给出两组时
s1 = {a,b,c,d} s2 = {b,c,d,a}
(即)
TableA
Item
a
b
c
d
TableB
Item
b
c
d
a
如何编写Sql查询以显示“tableA和tableB中的元素相等”。 [不使用SP或UDF]
输出
Elements in TableA and TableB contains identical sets
答案 0 :(得分:9)
使用:
SELECT CASE
WHEN COUNT(*) = (SELECT COUNT(*) FROM a)
AND COUNT(*) = (SELECT COUNT(*) FROM b) THEN 'Elements in TableA and TableB contains identical sets'
ELSE 'TableA and TableB do NOT contain identical sets'
END
FROM (SELECT a.col
FROM a
INTERSECT
SELECT b.col
FROM b) x
测试:
WITH a AS (
SELECT 'a' AS col
UNION ALL
SELECT 'b'
UNION ALL
SELECT 'c'
UNION ALL
SELECT 'd'),
b AS (
SELECT 'b' AS col
UNION ALL
SELECT 'c'
UNION ALL
SELECT 'd'
UNION ALL
SELECT 'a')
SELECT CASE
WHEN COUNT(*) = (SELECT COUNT(*) FROM a)
AND COUNT(*) = (SELECT COUNT(*) FROM b) THEN 'yes'
ELSE 'no'
END
FROM (SELECT a.col
FROM a
INTERSECT
SELECT b.col
FROM b) x
答案 1 :(得分:5)
这样的事情,使用FULL JOIN
:
SELECT
CASE
WHEN EXISTS (
SELECT * FROM s1 FULL JOIN s2 ON s1.Item = s2.Item
WHERE s1.Item IS NULL OR s2.Item IS NULL
)
THEN 'Elements in tableA and tableB are not equal'
ELSE 'Elements in tableA and tableB are equal'
END
这具有在第一次不匹配时短路的优点,不同于需要对每个表进行2次完全扫描的其他解决方案(一次用于COUNT(*),一次用于JOIN / INTERSECT)。
估计成本明显低于其他解决方案。
答案 2 :(得分:3)
我的怪物:
;with SetA as
(select 'a' c union
select 'b' union
select 'c')
, SetB as
(select 'b' c union
select 'c' union
select 'a' union
select 'd'
)
select case (select count(*) from (
select * from SetA except select * from SetB
union
select * from SetB except select * from SetA
)t)
when 0 then 'Equal' else 'NotEqual' end 'Equality'
答案 3 :(得分:3)
注意,我要使用交叉加入。
Declare @t1 table(val varchar(20))
Declare @t2 table(val varchar(20))
insert into @t1 values ('a')
insert into @t1 values ('b')
insert into @t1 values ('c')
insert into @t1 values ('d')
insert into @t2 values ('c')
insert into @t2 values ('d')
insert into @t2 values ('b')
insert into @t2 values ('a')
select
case when
count(1) =
(((Select count(1) from @t1)
+ (Select count(1) from @t2)) / 2.0)
then 1 else 0 end as SetsMatch from
@t1 t1 cross join @t2 t2
where t1.val = t2.val
答案 4 :(得分:2)
可以使用EXCEPT和案例
来完成select
case
when count (1)=0
then 'Elements in TableA and TableB contains identical sets'
else 'Nope' end from (
select item from s1
EXCEPT
select item from s2
) b
答案 5 :(得分:1)
由于这个帖子对我很有帮助,我以为我会分享我的解决方案。
我有类似的问题,或许比这个特定的单组比较更普遍适用。我试图找到一个元素的id,该元素具有一组与多元素项的查询集匹配的多元素子元素。
相关的架构信息是:
table events, pk id
table solutions, pk id, fk event_id -> events
table solution_sources, fk solutionid -> solutions
columns unitsourceid, alpha
查询:找到id为110的事件的解决方案,该事件具有与ss_tmp中的(unitsourceid,alpha)集匹配的solution_sources集。 (我相信,这也可以在没有tmp表的情况下完成。)
解决方案:
with solutionids as (
select y.solutionid from (
select ss.solutionid, count(ss.solutionid) x
from solutions s, solution_sources ss
where s.event_id = 110 and ss.solutionid = s.id
group by ss.solutionid
) y where y.x = ( select count(*) from ss_tmp )
)
select solutionids.solutionid from solutionids where
(
select case
when count(*) = ( select count(*) from ss_tmp ) then true
else false
end
from
( SELECT unitsourceid, alpha FROM solution_sources
where solutionid = solutionids.solutionid
INTERSECT
SELECT unitsourceid, alpha FROM ss_tmp ) x
)
针对4个项目的测试查询和具有匹配解决方案的测试数据库(相同数量的子元素,每个匹配),几个完全不匹配的解决方案和1个具有3个匹配子元素的解决方案进行测试,1解决方案包含所有4个匹配的子元素,另外还有一个子元素,以及1个包含4个子元素的解决方案,其中4个子元素中的3个与查询匹配。只返回了真匹配的id。
非常感谢 -Linus