Oracle Query Subselect with order by

时间:2012-05-24 10:12:25

标签: oracle sql-order-by greatest-n-per-group subquery

我通常使用MS SQL,并且是oracle的新手。

当我在子查询中使用ORDER BY语句时,我遇到了oracle驱动程序问题。

示例(我的真实陈述要复杂得多,但我怀疑这对我的问题很重要 - 如果需要我可以发布):

SELECT col1
     , col2
     , (SELECT colsub FROM subtbl WHERE idsub = tbl.id AND ROWNUM=1 ORDER BY coldate) col3
FROM tbl

如果我做了这样的构造,我得到一个odbc驱动程序错误:ORA-00907:缺少右括号(从德语翻译,所以括号可能是其他词:))。

如果删除ORDER BY coldate,一切正常。我找不到任何理由,所以我错了什么?

3 个答案:

答案 0 :(得分:2)

你做错了很清楚。您在子查询中使用订单。在子查询中使用订单没有任何意义,那么为什么要这样做呢? 您还在一个总是返回1行的子查询中使用order by。这也没有任何意义。

如果要对查询结果进行排序,请使用最高级别的订单。

答案 1 :(得分:2)

尝试:

select
  col1,
  col2,
  colsub
from(
  select
    col1   ,
    col2   ,
    coldate,
    max(coldate) over (partition by st.idsub) max_coldate
  from
    tbl    t,
    subtbl st
  where
    st.idsub = t.id)
where
  coldate = max_coldate

答案 2 :(得分:2)

以这种方式编写ROWNUM和ORDER是没有任何意义的,因为ORDER BY是在WHERE子句之后计算的,这意味着它在这种情况下没有效果。 this question中给出了一个例子。

这也有点复杂,因为如果子查询嵌套太深,很难将子查询加回到主查询。

下面的查询不一定有效,因为你不能以这种方式在tbl和subtbl之间加入。

SELECT 
  col1,
  col2,
  (
    select colsub
    from  (
      SELECT colsub 
       FROM subtbl 
       WHERE idsub = tbl.id
       order by coldate
    )
    where rownum = 1
  ) as col3
FROM tbl

因此,您需要使用某种分析函数,如下例所示:

SELECT 
  col1,
  col2,
  (SELECT max(colsub) keep (dense_rank first order by coldate) as colsub
   FROM subtbl 
   WHERE idsub = tbl.id
   group by idsub
) col3
FROM tbl

FIRST分析函数比它需要的更复杂,但它可以完成工作。

另一个选择是使用ROW_NUMBER解析函数,这也可以解决问题。

SELECT 
  col1,
  col2,
  (select colsub
   from (
     SELECT 
       idsub, 
       row_number() over (partition by idsub order by coldate) as rown,
       colsub
   FROM subtbl a 
   ) a
   WHERE a.idsub = tbl.id
   and a.rown = 1
) col3
FROM tbl