在plsql中将表与自身进行比较

时间:2011-12-16 21:39:56

标签: sql oracle 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#来传输新记录,但是,它会有不同的{{1 (如第2行所示)。

为了使其更加复杂,用户可以返回系统并更改Verified_Date值,这将生成第三条记录,该记录将具有不同的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,{{1} },Initial_Verified_DtFinal_Verified_Dt。我写了一个查询来比较表与自身,并返回Initial_Severity相同的所有值,但Final_Severity是不同的。问题是我得到以下结果:

ID#

我得到了所有组合,我无法弄清楚如何将表格与自身进行比较并得出正确的答案。我希望我能够清楚地解释清楚,并提前感谢你的帮助。

2 个答案:

答案 0 :(得分: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,您可以将所有这些小的子选项放入函数中,如果您愿意的话。我做了一个环绕选择只是为了让分组更容易。

答案 1 :(得分: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()函数允许您检查游标/结果集中的上一行(我假设verify_date列可以安全地用于按时间顺序排列记录);这样您就可以轻松检查自上一次记录相同缺陷后是否有变化。类似地,LEAD()函数允许您检查游标中的下一行。