如何找到几个键值元素的重叠时间片

问题描述 投票:2回答:1

我想知道我是否有重叠的时间片具有相同的ID和相同的名称。在以下示例中,id = 2和name = c的条目重叠。 id = 1的条目只是为了证明一个好的案例。

给定表:

+---+------+-------+------------+--------------+
|id | name | value | validFrom  |  validTo     |
+---+------+-------+------------+--------------+
|1  | a    | 12    | 2019-01-01 |  9999-12-31  |
|1  | b    | 34    | 2019-01-01 |  2019-10-31  |
|1  | b    | 35    | 2019-11-01 |  9999-12-31  |
|1  | c    | 13    | 2019-01-01 |  2025-12-31  |
|2  | a    | 49    | 2019-01-01 |  9999-12-31  |
|2  | b    | 99    | 2019-01-01 |  2034-12-31  |
|2  | c    | 75    | 2019-01-01 |  2019-10-31  |
|2  | c    | 84    | 2019-10-28 |  9999-12-31  |
|n  | ...  | ...   | ...        |  ...         |
+---+------+-------+------------+--------------+

预期产量:

+---+------+
|id | name |
+---+------+
|2  | c    |
+---+------+

感谢您的帮助!

sql sql-server
1个回答
3
投票

您可以使用exists获取重叠的行:

select t.*
from t
where exists (select 1
              from t t2
              where t2.id = t.id and
                    t2.name = t.name and
                    t2.value <> t.value and
                    t2.validTo > t.validFrom and
                    t2.validFrom < t.validTo
             );

如果你只想要id / name组合:

select distinct t.id, t.name
from t
where exists (select 1
              from t t2
              where t2.id = t.id and
                    t2.name = t.name and
                    t2.value <> t.value and
                    t2.validTo > t.validFrom and
                    t2.validFrom < t.validTo
             );

您还可以使用累积最大值执行此操作:

select t.*
from (select t.*,
             max(validTo) over (partition by id, name 
                                order by validFrom
                                rows between unbounded preceding and 1 preceding
                               ) as prev_validTo
      from t
     ) t
where prev_validTo >= validFrom;
© www.soinside.com 2019 - 2024. All rights reserved.