Импала Query, чтобы получить следующую дату - PullRequest
2 голосов
/ 22 апреля 2020

У меня есть 2 стола Impala.

1-я таблица T1 (есть дополнительные столбцы, но меня интересует только тип даты и дня в качестве дня недели):

date       day_type
04/01/2020 Weekday
04/02/2020 Weekday
04/03/2020 Weekday
04/04/2020 Weekend
04/05/2020 Weekend
04/06/2020 Weekday

2-я таблица T2:

process date       status
A       04/01/2020 finished
A       04/02/2020 finished
A       04/03/2020 finished
A       04/03/2020 run_again

Используя запросы Impala, я должен получить максимальную дату из второй таблицы T2 и получить ее статус. Согласно приведенной выше таблице 04/03 является максимальной датой. Если статус заканчивается 04/03, то мой запрос должен вернуть следующую доступную дату дня недели с T1, которая 04/06/2020. Но если статус run_again, то запрос должен вернуть ту же дату. В приведенной выше таблице 04/03 имеет run_again, и когда мой запрос выполняется, вывод должен быть 04/03/2020, а не 04/06/2020. Обратите внимание, что на дату возможно более одного статуса. Например, 04/03/2020 может иметь строку с готовым статусом, а другую с повторным выполнением статуса. В этом случае повторный запуск должен иметь приоритет, а в запросе должна быть дата 03.03.2020 в качестве даты вывода

Что я пробовал до сих пор: я запустил подзапрос из второй таблицы и получил максимальную дату и ее состояние. Я попытался запустить case в моем основном запросе и дал T1 в качестве подвыбора в выражении Case, но он не работает.

Можно ли добиться этого с помощью запроса Impala?

Ответы [ 2 ]

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

Один из способов сделать это - создать CTE из таблицы T1 вместо коррелированного подзапроса. Что-то вроде:

WITH T3 as (
  select t.date date, min(x.date) next_workday
  from T1 t join T1 x
  on t.date < x.date
  where x.day_type = 'Weekday'
  group by t.date
)
select T2.process, T2.date run_date, T2.status,
  case when T2.status = 'finished' then T3.next_workday
  else T3.date
  end next_run_date
from T2 join T3
on T2.date = T3.date
order by T2.process, T2.date;
+---------+------------+-----------+---------------+
| process | run_date   | status    | next_run_date |
+---------+------------+-----------+---------------+
| A       | 2020-04-01 | finished  | 2020-04-02    |
| A       | 2020-04-02 | finished  | 2020-04-03    |
| A       | 2020-04-03 | run again | 2020-04-03    |
+---------+------------+-----------+---------------+

Вы можете выбрать максимум из результата вместо упорядочения.

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

Может быть несколько решений, и даже несколько лучших, учитывая производительность, но это мой подход. Надеюсь, это поможет.

select case when status='run_again' then t2_date else t1_date end as needed_date from t2 cross join (select t1_date from t1 where t1.day_type='Weekday' and t1_date>(select max(t2_date) from t2) order by t1.t1_date limit 1)a where t2_date=(select max(t2_date) from t2);
...