ORA-00907: отсутствует правая скобка в ORACLE SQL неожиданная проблема с круглыми скобками - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь выполнить запрос SQL, чтобы решить эту проблему: ** Запросить два города в STATION с самыми короткими и длинными названиями CITY, а также их соответствующие длины (то есть: количество символов в имени) , Если существует более одного наименьшего или наибольшего города, выберите тот, который стоит первым в алфавитном порядке. Пример ввода: допустим, что CITY имеет только четыре записи: DEF, AB C, PQRS и WXY. Пример вывода: AB C 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. Может кто-нибудь указать на мою ошибку здесь?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Нельзя использовать ORDER BY в подзапросе, связанном с операторами UNION, UNION ALL, MINUS или INTERSECT

В обоих подзапросах UNION ALL используется ORDER BY что недопустимо (см. здесь, https://docs.oracle.com/database/121/SQLRF/queries004.htm#SQLRF52341).

Я бы просто бросил эти подзапросы (или блоки запросов) в обычные табличные выражения и выполнял там вашу работу.

Общее табличное выражение разрешает использование:

-заказа

-ограничивающего предложения

Я использовал нижеприведенную схему HR-инструкций.

В среде 11G, как заявляли Гордон Линофф и др., Ограничивающие строки пункты не существовали. Вы бы сделали что-то вроде этого:

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 12 c:

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

Вы пропустили сегмент, { ONLY | WITH TIES } ]

0 голосов
/ 22 апреля 2020

Вы имеете в виду

FETCH first 1 rows only;

или

FETCH FIRST ROW ONLY;

Как уже упоминалось, этот синтаксис недоступен в 11g

...