给出如下表格:
id key val
---- ---- -----
bob hair red
bob eyes green
还有另一张表:
id key val
---- ---- -----
fred hair red
fred eyes green
fred shoe 42
joe hair red
joe eyes green
greg eyes blue
greg hair brown
我想在表b中找到与表中的人完全匹配的人,在这种情况下是Bob和Joe。弗雷德不算数,因为他也有鞋码。这是在Sybase中,因此没有完全外连接。我想出了一个选择了一个带有联盟的选择,它可以归还那些肯定不一样的人,但我不确定如何有效地选择那些人。
或者,如果它更简单,我怎样才能多次检查b中出现哪些组?
答案 0 :(得分:2)
您可以通过抓取子查询中的所有full outer join
来模拟id
,然后将其连接到两个方向:
select ids.id
from (
select distinct id
from @a
union
select id
from @b
) as ids
left join
@a a1
on a1.id = ids.id
left join
@b b1
on a1.id = b1.id
and a1.[key] = b1.[key]
and a1.val = b1.val
left join
@b b2
on b2.id = ids.id
left join
@a a2
on b2.id = a2.id
and b2.[key] = a2.[key]
and b2.val = a2.val
group by
ids.id
having sum(case when b1.id is null or a2.id is null then 1 else 0 end) = 0
答案 1 :(得分:2)
试试这个
select a.id,b.id
from a
join b on a.[key] = b.[key] and a.val = b.val -- match all rows
join (select id,count(*) total from a group by id) a2 on a.id = a2.id -- get the total keys for table a per id
join (select id,count(*) total from b group by id) b2 on b.id = b2.id -- get the total keys for table b per id
group by a.id,b.id,a2.total,b2.total
having count(*) = a2.total AND count(*) = b2.total -- the matching row's total should be equal with each tables keys per id
在@t-clausen.dk评论后,我修改了原始的sql代码。 在这种情况下,我计算在两个表上匹配的每个不同的对/值,每个表都是不同的对/值。
select td.aid,td.bid
from (
select a.id as aid,b.id as bid, count(distinct a.[key]+' '+a.val) total
from a
join b on a.[kry] = b.[key] and a.val = b.val
group by a.id,b.id
) td -- match all distinct attribute rows
join (select id,count(distinct [key]+' '+val) total from a group by id) a2 on td.aid = a2.id -- get the total distinct keys for table a per id
join (select id,count(distinct [key]+' '+val) total from b group by id) b2 on td.bid = b2.id -- get the total keys for table b per id
where td.total = a2.total AND td.total = b2.total -- the matching distinct attribute total should be equal with each tables distinct key-val pair
Tested on
Table a
bob hair red
bob eyes green
nick hair red
nick eyes green
nick shoe 45
Table b
fred hair red
fred eyes green
joe hair red
joe eyes green
fred shoe 42
答案 2 :(得分:1)
此语法将在@ t1和@ t2中找到不同名称的完全匹配。我道歉,因为是用MSSQL编写的。我希望它可以转换为Sybase。在玩了一整天后,我想分享这种美。我知道这些长脚本并不受欢迎。我希望无论如何都会有人赞美它。
此选择在@ t1内的@ t2上完全匹配。
我填写了此链接http://data.stackexchange.com/stackoverflow/q/108035/
中的表格DECLARE @t1 TABLE(id varchar(10), [key] varchar(10), val varchar(10))
DECLARE @t2 TABLE(id varchar(10), [key] varchar(10), val varchar(10))
;WITH t1 AS (
SELECT t1.id, t1.[key], t1.val, count(*) count1, sum(count(*)) OVER(PARTITION BY t1.id) sum1 FROM @t1 t1
GROUP BY t1.id, t1.[key], t1.val
), t2 as (
SELECT t2.id, t2.[key], t2.val, count(*) count1, sum(count(*)) OVER(PARTITION BY t2.id) sum1 FROM @t2 t2
GROUP BY t2.id, t2.[key], t2.val
), t3 AS (
SELECT t1.*, sum(t1.count1) OVER(PARTITION BY t1.id) sum2
FROM t1
JOIN t2 on t1.val = t2.val AND t1.[key]=t2.[key]
AND t1.count1 = t2.count1 AND t1.sum1 = t2.sum1
)
SELECT t3.id, t3.[key], t3.val FROM t3
JOIN @t2 t ON t3.[key] = t.[key] AND t3.val = t.val
WHERE t3.sum2 = t3.sum1
不要尝试脚本,它不包含数据,请使用填充表的链接。