【问题标题】:Order by in sub query using oracle使用 oracle 在子查询中排序
【发布时间】:2021-10-06 11:46:02
【问题描述】:

在对子查询的记录进行排序后,我尝试从子查询中获取值,但是在执行查询时发生了以下情况: ORA-00907:缺少右括号

查询是:

select S.value , nvl((select D.value  from D
                join  T on D.subID = t.SubID
                where  D.subid2 = s.subid2 and t.subid3 = s.subid3    and rownum = 1 order by t.id),0 ) value

from   S

【问题讨论】:

  • 表格代表无序数据集。子查询结果是一个表。由于这个原因,在子查询中使用ORDER BY 是没有意义的,甚至禁止使用ORDER BY 子句结束子查询(Oracle 中该规则有一个例外,但我们忽略它)。对结果进行排序没有任何意义,因为使用rownum = 1 您可以选择一行。如果您对包含一行的列表进行排序,那么您当然会得到相同的单行。
  • 如果 rownum = 1 意味着在您的子查询中 order by 之后发生,以便获得最低 t.id 的 d.value,您可以将 and rownum = 1 order by t.id 更改为 order by t.id fetch first row only,这是允许的,因为ORDER BY 不是查询中的最后一个子句,因此不对结果进行排序,而只是为 fetch 子句准备中间结果集。另一种选择是 Oracle 的 KEEP FIRST,您可以完全删除 and rownum = 1 order by t.id 并将 select D.value 替换为 select min(d.value) keep (dense_rank first order by t.id)

标签: oracle subquery


【解决方案1】:

子查询中不能有ORDER BY 子句。

看看这样的事情是否有帮助:使用 CTE(因为它看起来更好一些;如果你愿意,可以是一个 普通子查询)计算 所有行的序号,按t.id 列值排序。在外部(主)查询中,选择rn = 1 的行(应该act就像你的ORDER BY t.id + rownum = 1)。

WITH
   temp
   AS
      (SELECT s.VALUE s_value,
              d.VALUE d_value,
              ROW_NUMBER () OVER (ORDER BY t.id) rn
         FROM d
              JOIN t ON d.subid = t.subid
              JOIN s
                 ON     s.subid2 = d.subid2
                    AND s.subid3 = t.subid3)
SELECT s_value, NVL (d_value, 0) d_value
  FROM temp
 WHERE rn = 1

【讨论】:

    【解决方案2】:

    如果您使用的是 Oracle 12c 或更高版本,则可以使用 FETCH FIRST... 子句。

    SELECT S.VALUE,
           NVL ((  SELECT D.VALUE
                     FROM D JOIN T ON D.subID = t.SubID
                    WHERE D.subid2 = s.subid2 AND t.subid3 = s.subid3
                 ORDER BY t.id
                    FETCH FIRST 1 ROWS ONLY),
                0)    VALUE
      FROM S
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      相关资源
      最近更新 更多