如何查找服务器键值元素的重叠时间片

时间:2019-04-09 11:04:32

标签: sql sql-server

我想确定我是否有重叠的时间片,它们具有相同的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    |
+---+------+

谢谢您的帮助!

1 个答案:

答案 0 :(得分: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;