在Oracle 9.2.0.8中,我需要为另一个字段返回一个特定字段(LAB_SEQ)最大的记录集(它是一个顺序VARCHAR数组'0001','0002'等) (WO_NUM)。要选择最大值,我尝试按降序排序并选择第一行。我在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只允许相关子查询达到一个深度,并建议重写以避免子查询 - 这一点无法完成选择最大值的讨论。任何有助于执行此声明的帮助将不胜感激。
答案 0 :(得分: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_LOC
添加到分析函数的ORDER BY
子句中,或者是否需要将它们添加到WHERE
条款。
答案 1 :(得分: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感到有点不确定。