如何找到相等的子集?
How to find equal subsets?
我有一个带有子集的 table。如何找到与给定 ID 具有相同子集的 reader ID?例如:
输入reader = 4
预期输出:reader 1 和 5.
子集大小并不总是 = 3,因为示例中它可以是动态的。什么是正确的 SQL 查询?
declare @t table(
reader int not null,
book int,
pages int
)
insert into @t (reader, book, pages)
select 1, 1, 100 union
select 1, 2, 201 union
select 1, 3, 301 union
select 2, 1, 100 union
select 2, 3, 101 union
select 2, 3, 301 union
select 3, 1, 100 union
select 3, 2, 101 union
select 3, 3, 301 union
select 4, 1, 100 union
select 4, 2, 201 union
select 4, 3, 301 union
select 5, 1, 100 union
select 5, 2, 201 union
select 5, 3, 301
select * from @t
这有点麻烦,但您可以使用自连接:
with t as (
select t.*, count(*) over (partition by reader) as cnt
from @t t
)
select t.reader
from t left join
t t2
on t2.book = t.book and
t2.pages = t.pages and
t2.cnt = t.cnt and
t2.reader = 4
group by t.reader, t.cnt
having count(*) = t.cnt and
count(*) = count(t2.reader);
需要 left join
来避免子集关系。也就是说,拥有“4”的所有书籍以及额外的书籍。
这是处理关系除法的通用方法。它检查集合 x 是否包含集合 y 中的所有元素(也许更多):
with reqd as (
select book, pages
from @t
where reader = 1
)
select t.reader
from @t as t
inner join reqd on t.book = reqd.book and t.pages = reqd.pages
group by t.reader
having count(reqd.book) = (select count(*) from reqd)
我有一个带有子集的 table。如何找到与给定 ID 具有相同子集的 reader ID?例如:
输入reader = 4 预期输出:reader 1 和 5.
子集大小并不总是 = 3,因为示例中它可以是动态的。什么是正确的 SQL 查询?
declare @t table(
reader int not null,
book int,
pages int
)
insert into @t (reader, book, pages)
select 1, 1, 100 union
select 1, 2, 201 union
select 1, 3, 301 union
select 2, 1, 100 union
select 2, 3, 101 union
select 2, 3, 301 union
select 3, 1, 100 union
select 3, 2, 101 union
select 3, 3, 301 union
select 4, 1, 100 union
select 4, 2, 201 union
select 4, 3, 301 union
select 5, 1, 100 union
select 5, 2, 201 union
select 5, 3, 301
select * from @t
这有点麻烦,但您可以使用自连接:
with t as (
select t.*, count(*) over (partition by reader) as cnt
from @t t
)
select t.reader
from t left join
t t2
on t2.book = t.book and
t2.pages = t.pages and
t2.cnt = t.cnt and
t2.reader = 4
group by t.reader, t.cnt
having count(*) = t.cnt and
count(*) = count(t2.reader);
需要 left join
来避免子集关系。也就是说,拥有“4”的所有书籍以及额外的书籍。
这是处理关系除法的通用方法。它检查集合 x 是否包含集合 y 中的所有元素(也许更多):
with reqd as (
select book, pages
from @t
where reader = 1
)
select t.reader
from @t as t
inner join reqd on t.book = reqd.book and t.pages = reqd.pages
group by t.reader
having count(reqd.book) = (select count(*) from reqd)