Oracle SQL命令在子查询中的问题!

Kev*_*ker 14 sql oracle

我试图在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

dan*_*and 21

实际上,"排序"只对最外层的查询有意义 - 如果您在子查询中进行排序,则允许外部查询随意对结果进行加扰,因此子查询排序基本上没有任何作用.

看起来你只想获得大于pst.last_updated的最小last_updated - 当你把它看作最小值(聚合)时更容易,而不是第一行(这带来了其他问题,如果如果next_response有两行绑定?)

试一试.公平的警告,自从我在我面前使用Oracle几年后,我不习惯子查询作为列的语法; 如果爆炸了,我将在from子句中创建一个版本.

select
    ps.id, ps.created_date, pst.last_updated, pst.from_state, pst.to_state,
    (   select min(last_updated)
        from mwcrm.process_state_transition subpst
        where subpst.last_updated > pst.last_updated
          and subpst.process_state = ps.id) as next_response
from <the rest>
Run Code Online (Sandbox Code Playgroud)

  • 使用聚合而不是ROWNUM的+1.ROWNUM是doubleplusunrelationalthink. (3认同)
  • 我的+1使用MIN在哪里?-哭- (2认同)

Jus*_*ave 19

dcw和Dems都提供了适当的替代查询.我只是想解释为什么你的查询没有按照你期望的方式运行.

如果您的查询包含ROWNUM和ORDER BY,Oracle首先应用ROWNUM,然后应用ORDER BY.所以查询

SELECT *
  FROM emp
 WHERE rownum <= 5
 ORDER BY empno
Run Code Online (Sandbox Code Playgroud)

EMP表中获取任意5行并对其进行排序 - 几乎肯定不是预期的.如果要使用ROWNUM获取"前N行",则需要嵌套查询.这个查询

SELECT *
  FROM (SELECT *
          FROM emp
         ORDER BY empno)
 WHERE rownum <= 5
Run Code Online (Sandbox Code Playgroud)

对EMP表中的行进行排序并返回前5行.


Mat*_*lie 9

我自己也经历过这个,你必须使用ROW_NUMBER()和一个额外级别的子查询,而不是rownum ......

只是显示新的子查询,像......

(
  SELECT
    last_updated
  FROM
  (
    select
      last_updated,
      ROW_NUMBER() OVER (ORDER BY last_updated ASC) row_id
    from
      mwcrm.process_state_transition subpst
    where
      subpst.last_updated > pst.last_updated
      and subpst.process_state = ps.id
  )
    as ordered_results
  WHERE
    row_id = 1
)
  as next_response
Run Code Online (Sandbox Code Playgroud)


另一种方法是使用MIN代替......

(
  select
    MIN(last_updated)
  from
    mwcrm.process_state_transition subpst
  where
    subpst.last_updated > pst.last_updated
    and subpst.process_state = ps.id
)
  as next_response
Run Code Online (Sandbox Code Playgroud)