2011-12-16 5 views
2

自体にテーブルを比較します。このシステムでは私はこのようになります欠陥テーブル持ってPLSQL

Ref# ID# Severity Status Found_Date Verified_Date Resolve_Date 
1001 21 2  Verified 6/19/2011 6/25/2011 
1001 21 2  Verified 6/19/2010 9/18/2011 
1001 21 3  Fixed  6/19/2010 10/12/2011  10/12/2011 

を、ユーザーがVerified_Date(ライン1のように)を持つことになりますレコードを、入力することができます。

その後、ユーザがシステムに再度行くと変更を行うと、システムが同じRef#ID#で、新しいレコードをgenetateますすることができ、しかし、それは(2行目のように)異なるVerified_Dateを持つことになります。

は、それがさらに複雑、ユーザーがシステムに戻ることができます作成​​し、3番目のレコードを生成します Severity値を変更し、そのレコードはまだ別の Verified_Dateを持っていますが、それは「同じ Ref#とがありますするには ID#私は次の結果を返します。クエリを書いて使命を帯びた

:。

  Initial Final      Initial  Final 
Ref# ID# Severity Severity Status Found_Dt Verified_Dt Verified_Dt Resolve_Dt 
1001 21 2   3   Fixed 6/19/2011 9/18/2011 10/12/2011 10/12/2011 

上記Severity変更があったすべてのレコードを一覧表示されます、クエリの結果であると想定されたレコードとprese Initial_Verified_DtFinal_Verified_DtInitial_SeverityおよびFinal_Severityを指摘している上記のフォーマットでそれを指定します。テーブルをそれ自身と比較し、ID#が同じだが、severityが異なるすべての値を返すクエリを書きました。

  Initial Final      Initial  Final 
Ref# ID# Severity Severity Status Found_Dt Verified_Dt Verified_Dt Resolve_Dt 
1001 21 2   3   Fixed 6/19/2011 9/18/2011 10/12/2011 10/12/2011 
1001 21 3   2   Fixed 6/19/2011 9/18/2011 10/12/2011 10/12/2011 
1001 21 2   3   Fixed 6/19/2011 10/12/2011 9/18/2011 10/12/2011 
1001 21 3   2   Fixed 6/19/2011 10/12/2011 9/18/2011 10/12/2011 

私はすべての組み合わせを取得していますし、私は自分自身にテーブルを比較し、正しい答えを思い付くする方法を見つけ出すことはできません。問題は、私は次のような結果を得ることです。私はそれを十分に説明し、あなたの助けを事前に感謝したいと思います。決して

答えて

1

は、このエレガントな解決策であるが、それは動作します:

select REF# 
     ,ID# 
     ,INITIAL_SEVERITY 
     ,FINAL_SEVERITY 
     ,STATUS 
     ,FOUND_DT 
     ,INITIAL_VERIFIED_DT 
     ,FINAL_VERIFIED_DT 
     ,RESOLVE_DT 
from  (select REF# 
       ,ID# 
       ,(select SEVERITY 
        from DEFECT D2 
        where D2.REF# = D.REF# 
         and D2.ID# = D.ID# 
         and VERIFIED_DATE = (select min(VERIFIED_DATE) from DEFECT)) 
        as INITIAL_SEVERITY 
       ,(select SEVERITY 
        from DEFECT D2 
        where D2.REF# = D.REF# 
         and D2.ID# = D.ID# 
         and VERIFIED_DATE = (select max(VERIFIED_DATE) from DEFECT)) 
        as FINAL_SEVERITY 
       ,(select STATUS 
        from DEFECT D2 
        where D2.REF# = D.REF# 
         and D2.ID# = D.ID# 
         and VERIFIED_DATE = (select max(VERIFIED_DATE) from DEFECT)) 
        as STATUS 
       ,min(FOUND_DATE) over (partition by REF#) as FOUND_DT 
       ,(select min(VERIFIED_DATE) 
        from DEFECT D2 
        where D2.REF# = D.REF# and D2.ID# = D.ID# and D2.STATUS = 'Verified') 
        as INITIAL_VERIFIED_DT 
       ,(select max(VERIFIED_DATE) 
        from DEFECT D2 
        where D2.REF# = D.REF# and D2.ID# = D.ID# and D2.STATUS = 'Verified') 
        as FINAL_VERIFIED_DT 
       ,(select max(RESOLVE_DATE) 
        from DEFECT D2 
        where D2.REF# = D.REF# and D2.ID# = D.ID# and D2.STATUS = 'Fixed') 
        as RESOLVE_DT 
      from DEFECT D) 
group by REF# 
     ,ID# 
     ,INITIAL_SEVERITY 
     ,FINAL_SEVERITY 
     ,STATUS 
     ,FOUND_DT 
     ,INITIAL_VERIFIED_DT 
     ,FINAL_VERIFIED_DT 
     ,RESOLVE_DT 

あなたが好む場合は、関数にすべてのそれらのほとんどのサブ選択を置くことができ、PL/SQLを使用している場合。グループ化を簡単にするためにラップアラウンドを選択しました。

+0

私の質問に答えるために時間を割いてくれてありがとうJohn Doyleさん、どうもありがとうございました。それは私のテーブル全体にそれを適用するにはしばらくかかった、それは魅力のように動作します! –

1

私は、これはあなたが必要なものだと思う:

SELECT * 
FROM (
      SELECT ref# 
       , id# 
       , LAG(severity) OVER (PARTITION BY ref#, id# ORDER BY verified_date) AS initial_severity 
       , severity AS final_severity 
       , status 
       , found_date 
       , LAG(verified_date) OVER (PARTITION BY ref#, id# ORDER BY verified_date) AS initial_verified_date 
       , verified_date AS final_verified_date 
       , resolve_date 
      FROM defects 
     ) 
WHERE initial_severity <> final_severity 
ORDER BY ref# 
     , id# 
     , final_verified_date; 

LAG()機能を使用すると、カーソル/結果セット内の前の行を検査することができます(私はverified_date列が安全に時系列で記録を注文するために使用できることを前提と);同じ欠陥の前回の記録以来の変更があったかどうかを簡単に確認することができます。同様に、LEAD()関数を使用すると、カーソルの次の行を検査できます。

関連する問題