【问题标题】:ORA-00907: missing right parenthesis in ORACLE SQL unexpected parenthesis issueORA-00907: ORACLE SQL 意外括号问题中缺少右括号
【发布时间】:2020-08-05 17:18:14
【问题描述】:

我正在尝试执行一个 SQL 查询来解决这个问题:**用最短和最长的 CITY 名称查询 STATION 中的两个城市,以及它们各自的长度(即:名称中的字符数)。如果有多个最小或最大的城市,请选择按字母顺序排列的第一个城市。 样本输入: 假设 CITY 只有四个条目: DEF、ABC、PQRS 和 WXY 样本输出: ABC 3 PQRS 4

**

我能够使用 MySQL 解决这个挑战。但是我在尝试在 Oracle 中解决同样的问题时遇到了错误,尽管有细微的变化。这正是我正在尝试的:

(SELECT CITY ,length(CITY)
FROM STATION
ORDER BY length(CITY) ASC ,CITY FETCH FIRST 1 ROW)
UNION ALL
(SELECT CITY ,length(CITY)
FROM STATION
ORDER BY length(CITY) DESC ,CITY FETCH FIRST 1 ROW); 

我得到了错误:

ORDER BY length(CITY) ASC ,CITY FETCH FIRST 1 ROW) 
* 
ERROR at line 3: 
ORA-00907: missing right parenthesis 

我无法找出这里的错误,因为我能够在 MySQL 中以几乎类似的方式解决它。有人可以在这里指出我的错误吗?

【问题讨论】:

  • Oracle 11g 不支持FETCH FIRST,所以这可能是一个问题。
  • 我刚刚添加了它作为标签,我正在 Hackerrank 中执行此代码。我相信它们与版本无关。再次,你能告诉我是否使用 rownum 会更好。我尝试使用 rownum也收到了同样的错误。
  • Oracle 解析器经常说“缺少括号”,表示它遇到了意外情况。它指示错误的点 - 在这种情况下,ORDER BY- 通常在语法上是无效的。现有答案之一解释了为什么在这种特殊情况下不允许使用 ORDER BY。

标签: sql oracle oracle11g oracle-apex


【解决方案1】:

您不能在与 UNION、UNION ALL、MINUS 或 INTERSECT 运算符关联的子查询中使用 ORDER BY

您在UNION ALL 的两个子查询中都使用了ORDER BY,这是不允许的(参见此处,https://docs.oracle.com/database/121/SQLRF/queries004.htm#SQLRF52341)。

我只是将这些子查询(也称为查询块)放入公用表表达式中并在那里执行您的工作。

公用表表达式允许使用:

-按

排序

-行限制子句

我使用了下面的教学 HR 架构。

在 11G 环境中,正如 Gordon Linoff 等人所说,不存在行限制子句。你会做这样的事情:

WITH stations AS (
    SELECT
        ROW_NUMBER() OVER(ORDER BY length(city), city) rn,
        length(city)  city_length,
        city
    FROM
        locations
)
SELECT
    *
FROM
    stations
WHERE
    rn <= 1
UNION ALL
SELECT
    *
FROM
    stations
WHERE
    rn >= (SELECT MAX(rn) FROM stations)
ORDER BY
    1

在 11G 后的环境中,您可以利用行限制子句功能:

WITH stations_desc AS (
    SELECT
        length(city),
        city
    FROM
        locations stations
    ORDER BY
        length(city) DESC,
        city
    FETCH FIRST 1 ROWS ONLY
), stations_asc AS (
    SELECT
        length(city),
        city
    FROM
        locations stations
    ORDER BY
        length(city) ASC,
        city
    FETCH FIRST 1 ROWS ONLY
)
SELECT
    *
FROM
    stations_asc
UNION ALL
SELECT
    *
FROM
    stations_desc;


LENGTH(CITY)    CITY
-----------------------
 4              Bern
19              South San Francisco

这将产生你想要达到的结果。


顺便说一句,行限制子句的语法在 Oracle 12c 中如下:

[ OFFSET offset { ROW | ROWS } ]
[ FETCH { FIRST | NEXT } [ { rowcount | percent PERCENT } ]
    { ROW | ROWS } { ONLY | WITH TIES } ]

你省略了片段,{ ONLY | WITH TIES } ]

【讨论】:

  • An order by is 是允许的,但是您需要将每个查询放在括号之间(这对于 UNION 查询通常无用):dbfiddle.uk/…
  • @a_horse_with_no_name 谢谢。我看到它在 sql fiddle 中确实有效。当我在livesql.oracle.com (19c) 中执行你的 sql 时,它会抛出这个错误:ORA-20001: Query must begin with SELECT or WITH
  • 嗯,这是那个奇怪的网络界面的限制
【解决方案2】:

你是说

FETCH first 1 rows only;

或

FETCH FIRST ROW ONLY;

如前所述,此语法在 11g 中不可用

【讨论】:

    猜你喜欢
    • 2017-03-11
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 2016-02-20
    • 2018-07-18
    • 1970-01-01
    相关资源
    最近更新 更多