Разница между CASE и UPIVOT для определения максимальной даты по столбцам;ORA-00904 неверное сообщение - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть миллионы идентификаторов, и мне нужно найти максимальную дату из 3 разных дат для каждого идентификатора.
Затем мне нужна дата начала месяца максимальной даты.
Вот ссылка:

+---------+-----------+---------------+--------------------+
|   ID    |  SETUP_DT |  REINSTATE_DT | LOCAL_REINSTATE_DT |
+---------+-----------+---------------+--------------------+
| C111111 | 2018/1/1  | Null          | Null               |
| C111112 | 2015/12/9 | 2018/10/25    | 2018/10/25         |
| C111113 | 2018/10/1 | Null          | Null               |
| C111114 | 2018/10/6 | 2018/12/14    | 2018/12/14         |
+---------+-----------+---------------+--------------------+

И то, что я хочу, ниже:

+---------+-----------+
|   ID    |  APP_MON  |
+---------+-----------+
| C111111 | 2018/1/1  |
| C111112 | 2018/10/1 |
| C111113 | 2018/10/1 |
| C111114 | 2018/12/1 |
+---------+-----------+

Я пытаюсь использовать другой код для получения результата.

Когда я использовал case и unpivot длянайти некоторые конкретные идентификаторы, результат выглядит отлично.

/* case */
SELECT DIST_ID as ID, 
trunc(
case
    when REINSTATE_DT is not null and LOCAL_REINSTATE_DT is not null then greatest(LOCAL_REINSTATE_DT, REINSTATE_DT)
    when REINSTATE_DT is null and LOCAL_REINSTATE_DT is not null then LOCAL_REINSTATE_DT
    when REINSTATE_DT is not null and LOCAL_REINSTATE_DT is null then REINSTATE_DT
    else SETUP_DT
end, 'MM') AS CN_APP_MON
FROM DISTRIBUTOR
where DIST_ID in ('CN111111','CN111112','CN111113','CN111114');

/* unpivot */
SELECT DIST_ID as ID, 
trunc(MAX(Date_value),'MM') AS CN_APP_MON 
FROM DISTRIBUTOR
UNPIVOT (Date_value FOR Date_type IN (SETUP_DT, REINSTATE_DT, LOCAL_REINSTATE_DT))
where DIST_ID in ('CN111111','CN111112','CN111113','CN111114')
GROUP BY DIST_ID;

Однако, когда я изменяю условие и пытаюсь использовать период даты для извлечения данных, результат получается странным.Чтобы быть более конкретным, я попытался заменить

where DIST_ID in ('CN111111','CN111112','CN111113','CN111114')` <br>

на

where REINSTATE_DT
between TO_DATE('2018/01/01','yyyy/mm/dd') and TO_DATE('2018/01/02','yyyy/mm/dd')`

Но функция отмены не работала.Он показал:

ORA-00904: «REINSTATE_DT»: неверный идентификатор 00904. 00000 - «% s: неверный идентификатор»

Я хочу знать:

  1. Какой метод более эффективен или какой еще более эффективный способ сделать это?
  2. Почему метод unpivot не сработал?Какая разница между этими двумя методами?

Большое вам спасибо!

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Предполагая, что ваши даты хранятся в виде дат, вы можете сделать это, используя greatest().Я не фанат "магических" значений в запросах, поэтому мне нравится coalesce() для этой цели.

Все ваши строки, кажется, имеют setup_dt, его можно использовать как "по умолчанию", используяcoalesce().Итак:

select id,
       trunc(greatest(setup_dt,
                      coalesce(reinstate_dt, setup_dt,
                      coalesce(local_reinstate_dt, setup_dt)
                     ),
             'mm') as app_mon
from distributor;
0 голосов
/ 25 декабря 2018

Вам не нужны такие сложные задачи, greatest с функцией nvl решит вашу проблему.

with distributor( ID, setup_dt, reinstate_dt, local_reinstate_dt ) as
(
 select 'C111111',date'2018-01-01', Null, Null from dual union all
 select 'C111112',date'2015-12-09',date'2018-10-25',date'2018-10-25' from dual union all 
 select 'C111113',date'2018-10-01',Null,Null from dual union all
 select 'C111114',date'2018-10-06',date'2018-12-14',date'2018-12-14' from dual
)
 select id, trunc(greatest(nvl(setup_dt,date'1900-01-01'), 
                           nvl(reinstate_dt,date'1900-01-01'), 
                           nvl(local_reinstate_dt,date'1900-01-01')),'mm') 
                 as app_mon
   from distributor;

  ID     APP_MON
------- ----------
C111111 01.01.2018
C111112 01.10.2018
C111113 01.10.2018
C111114 01.12.2018

Rextester Demo

PS: использование столбцов SETUP_DT, REINSTATE_DT или LOCAL_REINSTATE_DT недопустимо В предложении where вашего запроса, поскольку они преобразуются в Date_type в unpivot часть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...