упорядочить и rownum во внутреннем запросе - PullRequest
0 голосов
/ 29 января 2020

У меня есть 2 связанные таблицы A an B 1 - n

Для всех записей A я хотел бы, чтобы запись B соответствовала следующим условиям

  • A .dep = B.dep
  • Нет записи в B, имеющей тот же год A
  • Я хочу получить запись обработки B для года, предшествующего году, предшествующему году A
  • Если существует более одной записи, возьмите одну с последним обновлениемDate
  • Если существует более одной записи, возьмите одну с последней записью creationDate
  • Если существует более чем одну запись берут одну с последним Id

Я попробовал следующее

Select ...
from A
     ...
     left join B same on A.dep=same.dep and A.year=same.year
     left join B last on A.dep=last.dep and A.year>last.year
where ...
      and same.id is null
      and (last.id is null or
           last.id = (select id from B where dep=A.dep and rownum=1 order by year desc, updateDate desc, creationDate desc, id desc))

Но у меня ошибка:

00907. 00000 -  "missing right parenthesis"

Но все скобки в порядке. Похоже, внутренний выбор не поддерживает порядок на

Есть идеи?

Ответы [ 3 ]

0 голосов
/ 29 января 2020

Действительно, внутренний подзапрос не поддерживает order by, поскольку он даст частичный набор результатов, который будет дополнительно обрабатываться внешним запросом.

Используйте order by, чтобы отсортировать результат на основе ваших требований, как только Получен набор результатов, соответствующий другим условиям фильтра.

Итак, в вашем случае сначала получите запрос, соответствующий условиям фильтра, а затем примените порядок на основе требований. Но если вы хотите, чтобы результаты внутреннего подзапроса были упорядочены в первую очередь, прежде чем применять их к внешнему / основному запросу, используйте объединение. Сначала создайте набор результатов на основе внутреннего подзапроса и присоедините его с псевдонимом к другим / основным результатам запроса с соответствующими условиями объединения.

0 голосов
/ 29 января 2020

Предполагая, что b.id уникален, вы можете сделать:

select a.*, b.*
from a left join
     b
     on b.dep = a.dep and
        b.year <= a.year and
        b.id = (select max(b2.id) keep (dense_rank first order by b2.year desc, b2.updatedate desc, b2.creationdate desc, b2.id desc)
                from b b2
                where b2.dep = b.dep 
               );
0 голосов
/ 29 января 2020

Это ORDER BY в подзапросе.

Если вы запустите его в SQL* Plus (или каком-либо инструменте, который показывает позицию ошибки), вы получите

SQL> select *
  2  from dept d
  3  where 1 = 1
  4    and d.deptno = (select e.deptno from emp e where e.ename = 'KING' order by e.sal);
  and d.deptno = (select e.deptno from emp e where e.ename = 'KING' order by e.sal)
                                                                    *
ERROR at line 4:
ORA-00907: missing right parenthesis

Итак:

SQL> select *
  2  from dept d
  3  where 1 = 1
  4    and d.deptno = (select e.deptno from emp e where e.ename = 'KING');

    DEPTNO DNAME                LOC
---------- -------------------- --------------------
        10 ACCOUNTING           NEW YORK

SQL>
...