我正在尝试查询只返回表中的最新行。
最初我在查询中使用了max(id) 但是当我使用序列并且我的集合被聚集时,我不能依赖序列作为它的乱序。 所以我决定根据创建时间订购并使用rownum选择顶行。
我使用了像
这样的东西SELECT A.id
FROM Table_A, Table_B B
WHERE A.status = 'COMPLETED'
AND B.name = 'some_name'
AND A.id = B.id
AND rownum = 1
order by A.Creation_Time;
这有些怎么回事我说错了42145。 如果我删除了rownum condtn,则顶级记录是不同的,例如45343;
答案 0 :(得分:8)
将rownum
与order by
一起使用时,您需要使用子查询。这与where
和order by
的评估顺序有关。所以,试试这个:
SELECT t.*
FROM (SELECT A.id
FROM Table_A JOIN
Table_B B
ON A.id = B.id
WHERE A.status = 'COMPLETED' AND B.name = 'some_name'
ORDER BY A.Creation_Time
) ab
WHERE rownum = 1;
我应该补充一点:Oracle 12支持fetch first 1 row only
,这更方便:
SELECT A.id
FROM Table_A JOIN
Table_B B
ON A.id = B.id
WHERE A.status = 'COMPLETED' AND B.name = 'some_name'
ORDER BY A.Creation_Time
FETCH FIRST 1 ROW ONLY;
答案 1 :(得分:-1)
你有意这么做吗? (指定订购DESC)
SELECT A.id
FROM Table_A, Table_B B
WHERE A.status = 'COMPLETED'
AND B.name = 'some_name'
AND A.id = B.id
AND rownum = 1
order by A.Creation_Time DESC;
编辑:显然指定订单DESC对您的查询至关重要。我不得不提升Gordon,因为他完全正确你需要限制排序后返回的行,所以他建议的方法是完美的。所以,对于那些阅读这篇文章的人来说,我想毫无疑问地确保在处理where子句之后但在排序或聚合之前(source)分配了rownum。
注意:和戈登的答案一样好,还有一个考虑因素可能会或可能不会在这里重要。看起来可能有重复的A.Creation_Time值,这可能会导致您看到非确定性行为,只要在执行该查询时可能返回哪些重复行。如果可能出现这个问题,Tom Kyte(与之前相同的链接)建议在order by子句中添加一些唯一的列值作为一个简单的闪避。例如:
SELECT t.id
FROM (SELECT *
FROM (SELECT A.id, A.Creation_Time
FROM Table_A A
JOIN Table_B B
ON A.id = B.id
WHERE A.status = 'COMPLETED' AND B.name = 'some_name'
)
ORDER BY Creation_Time, rowid DESC
) t
WHERE rownum = 1;
其中ROWID是一个可用于此目的的唯一伪列。