Oracle SQL order by 子查询问题!
我正在尝试在 Oracle SQL 中运行子查询,但它不允许我对子查询列进行排序。对子查询进行排序很重要,因为 Oracle 似乎随意选择返回的列中的哪一个返回到主查询。
<代码>
select ps.id, ps.created_date, pst.last_updated, pst.from_state, pst.to_state,
(select last_updated from mwcrm.process_state_transition subpst
where subpst.last_updated > pst.last_updated
and subpst.process_state = ps.id
and rownum = 1) as next_response
from mwcrm.process_state ps, mwcrm.process_state_transition pst
where ps.created_date > sysdate - 1/24
and ps.id=pst.process_state
order by ps.id asc
确实应该是:
select ps.id, ps.created_date, pst.last_updated, pst.from_state, pst.to_state,
(select last_updated from mwcrm.process_state_transition subpst
where subpst.last_updated > pst.last_updated
and subpst.process_state = ps.id
and rownum = 1
order by subpst.last_updated asc) as next_response
from mwcrm.process_state ps, mwcrm.process_state_transition pst
where ps.created_date > sysdate - 1/24
and ps.id=pst.process_state
order by ps.id asc
I am trying to run a subquery in Oracle SQL and it will not let me order the subquery columns. Ordering the subquery is important as Oracle seems to choose at will which of the returned columns to return to the main query.
select ps.id, ps.created_date, pst.last_updated, pst.from_state, pst.to_state, (select last_updated from mwcrm.process_state_transition subpst where subpst.last_updated > pst.last_updated and subpst.process_state = ps.id and rownum = 1) as next_response from mwcrm.process_state ps, mwcrm.process_state_transition pst where ps.created_date > sysdate - 1/24 and ps.id=pst.process_state order by ps.id asc
Really should be:
select ps.id, ps.created_date, pst.last_updated, pst.from_state, pst.to_state, (select last_updated from mwcrm.process_state_transition subpst where subpst.last_updated > pst.last_updated and subpst.process_state = ps.id and rownum = 1 order by subpst.last_updated asc) as next_response from mwcrm.process_state ps, mwcrm.process_state_transition pst where ps.created_date > sysdate - 1/24 and ps.id=pst.process_state order by ps.id asc
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
dcw 和民主党都提供了适当的替代查询。我只是想解释一下为什么您的查询没有按照您预期的方式运行。
如果您的查询包含 ROWNUM 和 ORDER BY,则 Oracle 首先应用 ROWNUM,然后应用 ORDER BY。因此,查询
从
EMP
表中获取任意 5 行并对它们进行排序——几乎可以肯定不是预期的结果。如果您想使用 ROWNUM 获取“前 N”行,则需要嵌套查询。此查询对 EMP 表中的行进行排序并返回前 5 行。
Both dcw and Dems have provided appropriate alternative queries. I just wanted to toss in an explanation of why your query isn't behaving the way you expected it to.
If you have a query that includes a ROWNUM and an ORDER BY, Oracle applies the ROWNUM first and then the ORDER BY. So the query
gets an arbitrary 5 rows from the
EMP
table and sorts them-- almost certainly not what was intended. If you want to get the "first N" rows using ROWNUM, you would need to nest the query. This querysorts the rows in the EMP table and returns the first 5.
实际上,“排序”仅对最外层查询有意义 - 如果您在子查询中排序,则允许外部查询随意打乱结果,因此子查询排序本质上不执行任何操作。
看起来您只想获得大于 pst.last_updated 的最小值 last_updated ——当您将其视为最小值(聚合)而不是第一行(这会带来其他问题,例如如果有两行与 next_response 相关?)
试一试。公平警告,距离我使用 Oracle 已经有几年了,我还不习惯子查询即列语法;如果这个问题发生了,我会在 from 子句中制作一个版本。
Actually "ordering" only makes sense on the outermost query -- if you order in a subquery, the outer query is permitted to scramble the results at will, so the subquery ordering does essentially nothing.
It looks like you just want to get the minimum last_updated that is greater than pst.last_updated -- its easier when you look at it as the minimum (an aggregate), rather than a first row (which brings about other problems, like what if there are two rows tied for next_response?)
Give this a shot. Fair warning, been a few years since I've had Oracle in front of me, and I'm not used to the subquery-as-a-column syntax; if this blows up I'll make a version with it in the from clause.
我自己经历过这种情况,你必须使用 ROW_NUMBER() 和一个额外的子查询级别,而不是 rownum...
只是显示新的子查询,例如...
另一种选择是使用 MIN 代替...
I've experienced this myself and you have to use ROW_NUMBER(), and an extra level of subquery, instead of rownum...
Just showing the new subquery, something like...
An alternative would be to use MIN instead...
已确认的答案是完全错误的。
考虑一个生成唯一行索引号的子查询。
例如 Oracle 中的
ROWNUM
。您需要子查询来创建用于分页目的的唯一记录号(见下文)。
考虑以下示例查询:
内部查询与 T0 上的查询完全相同,但
DISTINCT
。您不能将
ROWNUM
放在外部查询上,因为LEFT JOIN
可能会生成更多结果。如果您可以对内部查询 (
T1.Name DESC
) 进行排序,则内部查询中生成的ROWNUM
将匹配。由于您不能在子查询中使用 ORDER BY,因此数字将不会匹配并且毫无用处。
感谢上帝
ROW_NUMBER OVER (ORDER BY ...)
解决了这个问题。尽管并非所有数据库引擎都支持。
两种方法之一,
LIMIT
(不需要ORDER
)和ROW_NUMBER() OVER
将覆盖大多数数据库引擎。但如果您没有这些选项之一,例如
ROWNUM
是您唯一的选项,那么子查询上的ORDER BY
是必须的!The confirmed answer is plain wrong.
Consider a subquery that generates a unique row index number.
For example
ROWNUM
in Oracle.You need the subquery to create the unique record number for paging purposes (see below).
Consider the following example query:
The inner query is the exact same query but
DISTINCT
on T0.You can't put the
ROWNUM
on the outer query since theLEFT JOIN
(s) could generate many more results.If you could order the inner query (
T1.Name DESC
) the generatedROWNUM
in the inner query would match.Since you cannot use an
ORDER B
Y in the subquery the numbers wont match and will be useless.Thank god for
ROW_NUMBER OVER (ORDER BY ...)
which fixes this issue.Although not supported by all DB engines.
One of the two methods,
LIMIT
(does not requireORDER
) and theROW_NUMBER() OVER
will cover most DB engines.But still if you don't have one of these options, for example the
ROWNUM
is your only option then aORDER BY
on the subquery is a must!