Почему я получаю сообщение об ошибке отсутствует правая скобка ORA-00907

#sql #oracle

#sql #Oracle

Вопрос:

Я застрял в одной проблеме, и я понятия не имею, где я допустил ошибку. Поскольку я проверяю все и каждое решение, но я не вижу, что я сделал неправильно.

 SELECT
    o.OrderID,
    o.Order_date,
    o.status,
    o.OrderAcceptanceCommentsSaved,
    o.OrderFileAttachment, 
    o.HasErrors,
    o.ErrorsResolved,
    (SELECT ou.Status FROM order_unload ou WHERE ou.OrderID = o.OrderID
     AND rownum <= 1 ORDER BY ou.Id DESC) AS UnloadStatus
FROM
    orders o
WHERE
    ProjectID = 141
ORDER BY ou.Id DESC;
 

Проблема здесь вторая SELECT

 (SELECT ou.Status FROM order_unload ou WHERE ou.OrderID = o.OrderID
   AND rownum <= 1 ORDER BY ou.Id DESC) AS UnloadStatus) 
 

Однако, когда я хочу выполнить только второй ВЫБОР, я также получаю сообщение об ошибке

 o.OrderID invalid identifier
 

Может кто-нибудь направить меня и сказать, где я допустил ошибку? Что не так с этим запросом?

Комментарии:

1. Попробуйте заменить and rownum <= 1 order by ou.id desc на order by ou.id desc limit 1 ? Возможно, это оракул, о котором я не знаю. В противном случае синтаксис выглядит нормальным.

2. ПРЕДЕЛ 1 — это функция MySQL, поскольку я не знаю Oracle SQL

3. Хорошо, тогда я виноват. Ваш второй фрагмент показывает закрывающую скобку в самом конце, которой нет в первом фрагменте, это опечатка в вопросе?

4. Первый фрагмент выполняется правильно, единственная проблема заключается во втором ВЫБОРЕ ошибки. Даже когда я выполняю отдельно, я получаю ошибку

5. ou в вашем (основном) запросе нет псевдонима, поэтому вы не можете использовать order by ou.id в последней строке

Ответ №1:

У вас есть несколько проблем:

  1. ORDER BY Предложение не разрешено в коррелированном подзапросе, поэтому механизм SQL ожидает, что запрос завершится до ORDER BY и в этой точке будет закрывающая фигурная скобка. Удалите ORDER BY предложение во внутреннем select, и эта ошибка исчезнет (и вы получите другую ошибку).
  2. ROWNUM применяется перед ORDER BY вычислением, поэтому, даже если запрос был синтаксически корректным, он не будет делать то, что вы хотели, поскольку вы получите случайную строку (первую, которую прочитает механизм SQL), которой будет присвоено ROWNUM значение 1, а затем отбрасываются остальные строки, а затем этот единственный (случайная) строка будет упорядочена. Вы хотите сначала заказать, а затем получить первую строку.
  3. Вы используете ou.id для упорядочивания внешнего запроса, но ou псевдоним не отображается в этом внешнем выборе.

Вы можете использовать:

 SELECT o.OrderID,
       o.Order_date,
       o.status,
       o.OrderAcceptanceCommentsSaved,
       o.OrderFileAttachment, 
       o.HasErrors,
       o.ErrorsResolved,
       ou.status AS UnloadStatus
FROM   orders o
       LEFT OUTER JOIN (
         SELECT status,
                orderid,
                id,
                ROW_NUMBER() OVER ( PARTITION BY orderid ORDER BY id DESC ) AS rn
         FROM   order_unload
       ) ou
       ON ( o.orderid = ou.OrderID AND ou.rn = 1 )
WHERE  ProjectID = 141
ORDER BY ou.Id DESC;
 

db<>скрипка здесь