0

在 Oracle 9.2.0.8 中,我需要返回一个记录集,其中每个字段 (WO_NUM) 的特定字段 (LAB_SEQ) 最大(它是顺序 VARCHAR 数组“0001”、“0002”等) . 要选择最大值,我尝试按降序排序并选择第一行。我在 StackOverflow 上可以找到的所有内容都表明,唯一的方法是使用相关子查询。然后我在外部查询的 WHERE 子句中使用这个最大值来为每个 WO_NUM 获取我想要的行:

SELECT lt.WO_NUM, lt.EMP_NUM, lt.LAB_END_DATE, lt.LAB_END_TIME
FROM LAB_TIM lt WHERE lt.LAB_SEQ = (
   SELECT LAB_SEQ FROM (
      SELECT lab.LAB_SEQ FROM LAB_TIM lab WHERE lab.CCN='1' AND MAS_LOC='1'
          AND lt.WO_NUM = lab.WO_NUM ORDER BY ROWNUM DESC
   ) WHERE ROWNUM=1
)

但是,这会为 lt.WO_NUM 错误返回无效标识符。研究表明,ORacle 8 只允许关联子查询更深一层,并建议重写以避免子查询——选择最大值的讨论表明无法做到这一点。任何帮助执行此语句将不胜感激。

4

2 回答 2

3

您的相关子查询需要类似于

SELECT lt.WO_NUM, lt.EMP_NUM, lt.LAB_END_DATE, lt.LAB_END_TIME
FROM LAB_TIM lt WHERE lt.LAB_SEQ = (
   SELECT max(lab.LAB_SEQ)
     FROM LAB_TIM lab 
    WHERE lab.CCN='1' AND MAS_LOC='1'
      AND lt.WO_NUM = lab.WO_NUM 
  )

由于您使用的是 Oracle 9.2,因此使用相关子查询可能会更有效。我不确定谓词lab.CCN='1' AND MAS_LOC='1'在您当前的查询中做了什么,所以我不太确定如何将它们转换为分析函数方法。LAB_SEQ和的组合是WO_NUM不是唯一的LAB_TIM?您是否需要在CCN和上添加谓词MAS_LOC才能为每个 获得一个唯一的行WO_NUM?或者您是否使用这些谓词来减少输出中的行数?基本方法将类似于

SELECT *
  FROM (SELECT lt.WO_NUM, 
               lt.EMP_NUM, 
               lt.LAB_END_DATE, 
               lt.LAB_END_TIME,
               rank() over (partition by wo_num
                                order by lab_seq desc) rnk
          FROM LAB_TIM lt)
   WHERE rnk = 1

但我不清楚是否需要将它们添加到解析函数中的子句中CCN,或者是否需要将它们添加到子句中。MAS_LOCORDER BYWHERE

于 2012-05-23T15:19:13.437 回答
0

这是关联子查询更好的一种情况,尤其是在表上有索引的情况下。但是,应该可以将相关子查询重写为连接。

我认为以下是等价的,没有相关的子查询:

SELECT lt.WO_NUM, lt.EMP_NUM, lt.LAB_END_DATE, lt.LAB_END_TIME
FROM (select *, rownum as r
      from LAB_TIM lt
     ) lt join
     (select wo_num, max(r) as maxrownum
      from (select LAB_SEQ, wo_num, rownum as r
            from LAB_TIM lt
            where lab.CCN = '1' AND MAS_LOC = '1'
           ) 
     ) ltsum
     on lt.wo_num = ltsum.wo_num and
        lt.r = ltsum.maxrownum

我有点不确定 Oracle 如何在 ORDER BY 中使用 rownums。

于 2012-05-23T15:35:58.660 回答