3

I have a structure like this in a few tables: id, [...], validfrom, validto.

The id is a NUMBER, and the validfrom and validto columns are of type DATE. Any given date should not result in more than one post per id.

So this is a correct example:

id, validfrom, validto
1, 2000-01-01, 2000-02-20
1, 2000-02-21, 2000-03-02
1, 2000-03-03, 2099-12-31

However, there seem to be some issues where a certain dates would return more than one value. Something like this (which is corrupt data):

id, validfrom, validto
1, 2001-01-01, 2001-02-20
1, 2001-01-15, 2001-03-02
1, 2001-03-03, 2099-12-31

So in the above example, any date between 2001-01-15 and 2001-02-20 would return two rows.

How would I construct a script that finds all thees corrupt posts?

4

3 回答 3

2

只是为了找到它们,假设在每一行中 validfrom 都小于 validto :

select a.*, b.*
from your_table a
join your_table b
on (a.id = b.id and
    --overlapping
    greatest(a.validfrom, b.validfrom) <= least(a.validto, b.validto) and
    --exclude join the same row.
    a.rowid <> b.rowid
    )

这只是找到相交的区间,因为不同的区间的 valid_from 大于另一个的 valid_to。

UPDATE:我not (a.validto=b.validto and a.validfrom=b.validfrom)

a.rowid<> b.rowid

因为它现在会报告重复的行。(感谢沃尔夫)

于 2013-01-11T09:32:04.057 回答
2

寻找重叠的时间跨度是一场噩梦。很容易出错,而且我知道没有简单而好的解决方案。从理论上讲,Oracle 已经使用一种数据类型解决了这个问题,该数据类型WM_PERIOD可能会或可能不会在您的数据库中安装/可用。但这也不是美女:

SELECT *
  FROM your_table a JOIN your_table b USING (id) 
 WHERE a.rowid < b.rowid
   AND wm_overlaps(wm_period(a.validfrom, a.validto), 
                   wm_period(b.validfrom, b.validto))=1;

1 2001-01-01 2001-02-20 2001-01-15 2001-03-02
于 2013-01-11T11:03:18.067 回答
1

这将寻找重叠的行和重复的行:

select  *
from    YourTable yt1
where   -- Overlapping rows exist
        exists
        (
        select  *
        from    YourTable yt2
        where   yt1.id = yt2.id
                -- Rows overlap
                and yt1.validfrom <= yt2.validto
                and yt2.validfrom <= yt1.validto
                -- Rows must be distinct
                and yt1.rowid <> yt2.rowid
        )
于 2013-01-11T09:51:10.677 回答