鉴于以下内容:
declare @a table ( pkid int, value int ) declare @b table ( otherID int, value int ) insert into @a values (1, 1000) insert into @a values (1, 1001) insert into @a values (2, 1000) insert into @a values (2, 1001) insert into @a values (2, 1002) insert into @b values (-1, 1000) insert into @b values (-1, 1001) insert into @b values (-1, 1002)
如何查询@a中与@b完全匹配的所有值?
{@a.pkid = 1, @b.otherID = -1}
不会被退回(3个值中只有2个匹配)
{@a.pkid = 2, @b.otherID = -1}
将被退回(3个值中的3个匹配)
重构表可以是一种选择.
编辑:我在James和Tom H.的答案中取得了成功.
当我在@b中添加另一个案例时,它们会有点短暂.
insert into @b values (-2, 1000)
假设这应该返回另外两行({@a.pkid = 1, @b.otherID = -2}
并且{@a.pkid = 2, @b.otherID = -2}
,它不起作用.但是,对于我的项目,这不是问题.
这样更有效(它使用TOP 1
而不是COUNT
),并且可以使用(-2, 1000)
:
SELECT * FROM ( SELECT ab.pkid, ab.otherID, ( SELECT TOP 1 COALESCE(ai.value, bi.value) FROM ( SELECT * FROM @a aii WHERE aii.pkid = ab.pkid ) ai FULL OUTER JOIN ( SELECT * FROM @b bii WHERE bii.otherID = ab.otherID ) bi ON ai.value = bi.value WHERE ai.pkid IS NULL OR bi.otherID IS NULL ) unmatch FROM ( SELECT DISTINCT pkid, otherid FROM @a a , @b b ) ab ) q WHERE unmatch IS NOT NULL
可能不是最便宜的方式:
SELECT a.pkId,b.otherId FROM (SELECT a.pkId,CHECKSUM_AGG(DISTINCT a.value) as 'ValueHash' FROM @a a GROUP BY a.pkId) a INNER JOIN (SELECT b.otherId,CHECKSUM_AGG(DISTINCT b.value) as 'ValueHash' FROM @b b GROUP BY b.otherId) b ON a.ValueHash = b.ValueHash
你可以看到,基本上我正在为每个表创建一个新的结果集,表示每个表中每个Id的值集合的一个值,并且只在它们匹配的地方加入.