在Pl Sql中看似简单的查询

时间:2010-01-12 14:59:04

标签: sql oracle plsql greatest-n-per-group

我有以下格式的表“缺陷”:

id   status  stat_date   line   div  area
1    Open    09/21/09    F      A    cube
1    closed  01/01/10    F      A    cube
2    Open    10/23/09    B      C    Back
3    Open    11/08/09    S      B    Front
3    closed  12/12/09    S      B    Front   

我的问题是我想写一个只提取“开放”缺陷的查询。如果我编写一个查询来简单地提取所有打开的缺陷,那么我得到错误的结果,因为有一些缺陷, 有2条与之相关的记录。例如,使用我编写的查询,即使它们已关闭,我的结果中也会出现缺陷ID#s 1和3。我希望我能很好地解释我的问题。谢谢。

5 个答案:

答案 0 :(得分:2)

使用:

SELECT t.*
  FROM DEFECTS t
  JOIN (SELECT d.id,
               MAX(d.stat_date) 'msd'
          FROM DEFECTS d
      GROUP BY d.id) x ON x.id = t.id
                      AND x.msd = t.stat_date
 WHERE t.status != 'closed'
  1. 联接获取每个id值的最新日期。
  2. 根据iddate加入原始表格,以便只获取最新的行。
  3. 过滤掉已关闭状态的行以了解当前打开的行

答案 1 :(得分:1)

Select * 
from defects d
where status = 'Open'
and not exists (
   select 1 from defects d1
   where d1.status = 'closed'
   and d1.id = d.id
   and d1.stat_date > d.stat_date
)

答案 2 :(得分:1)

因此,您希望获得每个id及其中的最新行,只选择那些打开的行。这是常见greatest-n-per-group问题的变体。

我会这样做:

SELECT d1.*
FROM defects d1
LEFT OUTER JOIN defects d2
  ON (d1.id = d2.id AND d1.stat_date < d2.stat_date)
WHERE d2.id IS NULL
  AND d1.status = 'Open';

答案 3 :(得分:0)

这应该得到你想要的。我不会有打开和关闭缺陷的记录,而只是记录单个缺陷的记录。但这可能不是你可以轻易改变的东西。

SELECT id FROM defects 
WHERE status = 'OPEN' AND id NOT IN 
(SELECT id FROM defects WHERE status = 'closed')

答案 4 :(得分:0)

此查询处理多个打开/关闭/打开,只有一个通过数据(即没有自连接):

SELECT * FROM
(SELECT DISTINCT
        id
       ,FIRST_VALUE(status)
        OVER (PARTITION BY id
              ORDER BY stat_date desc)
        as last_status
       ,FIRST_VALUE(stat_date)
        over (PARTITION BY id
              ORDER BY stat_date desc)
        AS last_stat_date
       ,line
       ,div
       ,area
 FROM defects)
WHERE last_status = 'Open';