3

私はいくつかのテーブルにこのような構造を持っています:id、[...]、validfrom、validto。

idNUMBERであり、列validfromvalidto列はDATE型です。任意の日付で、1つの投稿が複数になることはありませんid

したがって、これは正しい例です。

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

ただし、特定の日付が複数の値を返すという問題があるようです。このようなもの(これは破損したデータです):

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

したがって、上記の例では、2001-01-15と2001-02-20の間の日付は2行を返します。

すべての破損した投稿を見つけるスクリプトを作成するにはどうすればよいですか?

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よりも大きいため、これは交差する間隔を見つけるだけです。

UPDATEnot (a.validto=b.validto and a.validfrom=b.validfrom) :条件を次のように置き換えました

a.rowid<> b.rowid

重複した行が報告されるためです。(ありがとうwolfi)

于 2013-01-11T09:32:04.057 に答える
2

重複する期間を見つけることは悪夢です。間違えるのは非常に簡単で、私が知っている単純で良い解決策はありません。理論的には、オラクルはこれをデータ型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 に答える