Search code examples
sqlsql-servert-sqlrelational-division

How to find equal subsets?


I have a table with subsets. How to find reader id's with the same subsets as given id? For example:

Input reader = 4 The expected output: reader 1 and 5.

Subsets size is not always = 3 as in the example it can be dynamic. What is correct SQL query?

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

Solution

  • This is a bit of a pain, but you can use a self-join:

    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);
    

    The left join is needed to avoid a subsetting relationship. That is, having all the books for "4" plus additional books.