Порядок в подзапросе и псевдоним - PullRequest
0 голосов
/ 25 сентября 2019

У меня проблема с заказом по в запросе оракула. ​​

select KEY, B, C, (select D from TABLE1 a where a.KEY = b.KEY and a.DATE< 
b.DATE order BY a.DATE and rownum =1 ) 
FROMSTATUS from TABLE2 b

Я знаю, что "заказ по" не работает в подзапросе.Я изменяю свой запрос как:

select KEY, B, C, (select * from (select D from TABLE1 a where a.KEY = 
b.KEY and a.DATE< b.DATE order by DATE) where rownum = 1)
FROMSTATUS from TABLE2 b

Но таким образом B.KEY и B.DATE не разрешаются оракулом

Мне нужно выбрать только 1 значение из TABLE2 и значениепервый предыдущий a.DATE

Пример:

 TABLE1
 KEY    DATE        A    B    C 
 1      01/31/2000  1    2    3
 2      02/25/2000  X    Y    Z   

 TABLE2
 KEY    DATE          D
 1      01/30/2000    1
 1      01/27/2000    2
 1      01/25/2000    2
 2      02/20/2000    4
 2      02/13/2000    1

Мне нужен этот результат:

TABLE1.KEY   TABLE1.DATE    TABLE1.A TABLE1.B TABLE1.C TABLE2.DATE TABLE2.D
1            01/31/2000     1        2        3        01/30/2000  1
2            02/25/2000     X        Y        Z        02/20/2000  4

Можете ли вы помочь мне?

(прошу прощения за мой плохой английский)

Ответы [ 4 ]

1 голос
/ 25 сентября 2019

В Oracle вы можете использовать KEEP LAST для этого:

select
  key,
  b,
  c,
  (
    select max(d) keep (dense_rank last order by t2.date)
    from table2 t2
    where t2.key = t1.key and t2.date < t1.date
  ) as fromstatus
from table1 t1;

Начиная с Oracle 12c, вы также можете использовать FETCH FIRST ROW:

select
  key,
  b,
  c,
  (
    select d
    from table2 t2
    where t2.key = t1.key and t2.date < t1.date
    order by t2.date desc
    fetch first row only
  ) as fromstatus
from table1 t1;

или, перемещая подзапрос впредложение FROM:

select
  t1.key,
  t1.b,
  t1.c,
  first_t2.d as fromstatus
from table1 t1
outer apply
(
  select d
  from table2 t2
  where t2.key = t1.key and t2.date < t1.date
  order by t2.date desc
  fetch first row only
) first_t2;

Этот последний запрос имеет то преимущество, что вы можете легко выбрать больше значений из строки таблицы 2, чем одно.

1 голос
/ 25 сентября 2019

Для этого вы можете использовать оконные функции:

WITH cte AS (
    SELECT TABLE2.KEY, TABLE2.B, TABLE2.C, TABLE1.D
         , ROW_NUMBER() OVER (PARTITION BY TABLE2.KEY, TABLE2.DATE ORDER BY TABLE1.DATE DESC) AS rn
    FROM TABLE2
    LEFT JOIN TABLE1 ON TABLE2.KEY = TABLE1.KEY AND TABLE2.DATE > TABLE1.DATE
)
SELECT *
FROM cte
WHERE rn = 1
1 голос
/ 25 сентября 2019

Вот ответ, который использует агрегирование:

WITH t1 AS (SELECT 1 KEY, to_date('31/01/2000', 'dd/mm/yyyy') dt FROM dual UNION ALL
            SELECT 2 KEY, to_date('25/02/2000', 'dd/mm/yyyy') dt FROM dual),
     t2 AS (SELECT 1 KEY, to_date('30/01/2000', 'dd/mm/yyyy') dt FROM dual UNION ALL
            SELECT 1 KEY, to_date('27/01/2000', 'dd/mm/yyyy') dt FROM dual UNION ALL
            SELECT 1 KEY, to_date('25/01/2000', 'dd/mm/yyyy') dt FROM dual UNION ALL
            SELECT 2 KEY, to_date('20/02/2000', 'dd/mm/yyyy') dt FROM dual UNION ALL
            SELECT 2 KEY, to_date('13/02/2000', 'dd/mm/yyyy') dt FROM dual)
SELECT t1.KEY,
       t1.dt t1_date,
       MAX(t2.dt) t2_date
FROM   t1
       LEFT OUTER JOIN t2 ON t1.key = t2.key AND t2.dt < t1.dt
GROUP BY t1.key, t1.dt
ORDER BY t1.key;

       KEY T1_DATE     T2_DATE
---------- ----------- -----------
         1 31/01/2000  30/01/2000
         2 25/02/2000  20/02/2000

Я предполагаю, что t1.key является уникальным столбцом.Является ли это более эффективным, чем любой другой ответ для ваших данных, зависит от вас, чтобы проверить * {: -)

1 голос
/ 25 сентября 2019

row_number() после того, как union получит ваш вывод.

 select tFinal.DATE, tFinal.KEY 
 from (select row_number() over (partition by KEY order by t1.T, t1.DATE desc) as rn, t1.DATE, t1.KEY 
        from 
        (select DATE, KEY, 't1' as T from TABLE1
        union all
        select DATE, KEY, 't2' as T from TABLE2) t1) tFinal
 Where rn = 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...