简体   繁体   English

SQL - 查找所有组合

[英]SQL - find all combinations

From a dataset like this, I need to get all possible combinations of cases in the same room so that no case overlaps another.从这样的数据集中,我需要在同一个房间中获得所有可能的案例组合,以便没有案例与另一个重叠。

room        case        start               end
a           1           2019-11-27 09:00    2019-11-27 10:15
a           2           2019-11-27 10:30    2019-11-27 12:00
a           3           2019-11-27 12:00    2019-11-27 12:30
b           4           2019-11-27 08:30    2019-11-27 10:30
b           5           2019-11-27 10:00    2019-11-27 12:00
b           6           2019-11-27 11:00    2019-11-27 12:20

The expected result is预期的结果是

room        combination         cases   
a           1                   1
a           2                   1,2
a           3                   1,2,3
a           4                   2
a           5                   2,3
a           6                   3
b           1                   4
b           2                   4,6
b           3                   5
b           4                   6

I am able to get single line results of what case can be combined with which other case like:我能够获得哪种情况可以与其他情况相结合的单行结果,例如:

room        case        combinewithcase
a           1           2
a           1           3
a           2           1
a           2           3
a           3           1
a           3           2
b           4           6
b           6           4

And I've tried some recursions but I am at a loss nowhere near to getting the type of results I need, I would appreciate any guidance anyone can share.我已经尝试了一些递归,但我无法获得我需要的结果类型,我很感激任何人都可以分享的任何指导。

Here is one method using a string aggregation.这是使用字符串聚合的一种方法。 To get the overlaps by time:要按时间获得重叠:

select rd.room, rd.dte,
       (select string_agg(t2.case, ',') within group (order by t2.case)
        from t t2
        where t2.room = t.room and
              t2.start <= t.dte and
              t2.end > t.dte
       ) as cases
from ((select room, start as dte from t
      ) union -- on purpose to remove duplicates
      (select room, end from t
      )
     ) rd;

You can then use this as a subquery/CTE to enumerate the combinations:然后,您可以将其用作子查询/CTE 来枚举组合:

select room, cases, count(*),
       row_number() over (partition by room order by combination) as combination
from (select rd.room, rd.dte,
             (select string_agg(t2.case, ',') within group (order by t2.case)
              from t t2
              where t2.room = t.room and
                    t2.start <= t.dte and
                    t2.end > t.dte
             ) as cases
      from ((select room, start as dte from t
            ) union -- on purpose to remove duplicates
            (select room, end from t
            )
           ) rd
     ) rd
group by room, cases
order by room, cases;

EDIT:编辑:

In earlier versions of SQL Server, you can use the XML method for string aggregation:在早期版本的 SQL Server 中,您可以使用 XML 方法进行字符串聚合:

select room, cases, count(*),
       row_number() over (partition by room order by combination) as combination
from (select rd.room, rd.dte,
             stuff( (select concat(',', t2.case)
                     from t t2
                     where t2.room = t.room and
                           t2.start <= t.dte and
                           t2.end > t.dte
                     order by t2.case
                     for xml path
                    ), 1, 1, '')
             ) as cases
      from ((select room, start as dte from t
            ) union -- on purpose to remove duplicates
            (select room, end from t
            )
           ) rd
     ) rd
group by room, cases
order by room, cases;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM