SQL - Vertica: как генерировать ежедневные строки с большинством данных предыдущих дат - PullRequest
0 голосов
/ 14 октября 2019

У меня есть базовая таблица, как показано ниже:

score_upd (Upd_dt,Url,Score) AS (
          SELECT DATE '2019-07-26','A','x'
UNION ALL SELECT DATE '2019-07-26','B','alpha'
UNION ALL SELECT DATE '2019-08-01','A','y'
UNION ALL SELECT DATE '2019-08-01','B','beta'
UNION ALL SELECT DATE '2019-08-03','A','z'
UNION ALL SELECT DATE '2019-08-03','B','gamma'
)

   Upd_dt       URL    Score
 2019-07-26      A       x
 2019-07-26      B      alpha 
 2019-08-01      A       y
 2019-08-01      B      beta
 2019-08-03      A       z
 2019-08-03      B      gamma

И я хочу создать таблицу на уровне daily-url, используя большинство значений предыдущей даты для новых строк, результат должен выглядеть следующим образом:

score_upd (Upd_dt,Url,Score) AS (
          SELECT DATE '2019-07-26','A','x'
UNION ALL SELECT DATE '2019-07-26','B','alpha'
UNION ALL SELECT DATE '2019-07-27','A','x'
UNION ALL SELECT DATE '2019-07-27','B','alpha'
UNION ALL SELECT DATE '2019-07-28','A','x'
UNION ALL SELECT DATE '2019-07-28','B','alpha'
UNION ALL SELECT DATE '2019-07-29','A','x'
UNION ALL SELECT DATE '2019-07-29','B','alpha'
UNION ALL SELECT DATE '2019-07-30','A','x'
UNION ALL SELECT DATE '2019-07-30','B','alpha'
UNION ALL SELECT DATE '2019-07-31','A','x'
UNION ALL SELECT DATE '2019-07-31','B','alpha'
UNION ALL SELECT DATE '2019-08-01','A','y'
UNION ALL SELECT DATE '2019-08-01','B','beta'
UNION ALL SELECT DATE '2019-08-02','A','y'
UNION ALL SELECT DATE '2019-08-02','B','beta'
UNION ALL SELECT DATE '2019-08-03','A','z'
UNION ALL SELECT DATE '2019-08-03','B','gamma'
UNION ALL SELECT DATE '2019-08-04','A','z'
UNION ALL SELECT DATE '2019-08-04','B','gamma'
UNION ALL SELECT DATE '2019-08-05','A','z'
UNION ALL SELECT DATE '2019-08-05','B','gamma'
) 

Что выглядит следующим образом:

   Upd_dt       URL    Score 
 2019-07-26      A       x
 2019-07-26      B      alpha 
 2019-07-27      A       x
 2019-07-27      B      alpha 
 2019-07-28      A       x
 2019-07-28      B      alpha 
 2019-07-29      A       x
 2019-07-29      B      alpha 
 2019-07-30      A       x
 2019-07-30      B      alpha 
 2019-07-31      A       x
 2019-07-31      B      alpha 
 2019-08-01      A       y
 2019-08-01      B      beta
 2019-08-02      A       y
 2019-08-02      B      beta
 2019-08-03      A       z
 2019-08-03      B      gamma
 2019-08-04      A       z
 2019-08-04      B      gamma
 2019-08-05      A       z
 2019-08-05      B      gamma
.
.
.

Текущий процесс: Я построил таблицу ежедневных измерений с 26.07.2009 по сегодняшний день:

/ * SELECTCAST (slice_time AS DATE) датируется из testcalendar mtc TIMESERIES slice_time как '1 день' OVER (ORDER BY CAST (mtc.dates как TIMESTAMP));* /

, поэтому я получаю:

Даты

2019-07-26

2019-07-27

2019-07-28

2019-07-29

.

.

.

2019-10-12 (сегодня)

Я думаю, смогу ли я использовать такую ​​функцию, как «интерполировать предыдущее значение», чтобы соединить мою первую таблицу по датам, чтобы сгенерировать пропущенные дни, используя значения из большинства данных предыдущих дат, пока она не удалась.

Результат не сгенерировал строки за пропущенные дни.

Пожалуйста, дайте мне знать, если у кого-нибудь есть идеи по этому поводу.

Спасибо!

1 Ответ

0 голосов
/ 16 октября 2019

В качестве начального предупреждения: храните «ежедневную фотографию» только тогда, когда это действительно необходимо. В прошлом у меня было 364 строки в год, так как значения менялись только один раз в год. В Vertica это стоит лицензии, а также процессора и времени для объединения и группировки ...

Но в остальном - хорошее начало.

Но вы можете применять ВРЕМЕНИ без необходимости строитькалендарь.

Хитрость заключается в том, чтобы «экстраполировать» вручную то, что вы можете INTERPOLATE автоматически.

Добавить встроенную таблицу «заполнения», которая содержит новейшее значение для каждого URL, ноукажите CURRENT_DATE вместо самой новой фактической даты - используя своеобразное аналитическое предельное условие Vertica LIMIT 1 OVER(PARTITION BY url ORDER BY upd_dt DESC).

UNION ВЫБЕРИТЕ эту таблицу дополнений своим вводом и примените к ней предложение TIMESERIES. UNION SELECT.

Вот так:

WITH
-- your input ...
score_upd (Upd_dt,Url,Score) AS (
          SELECT DATE '2019-07-26','A','x'
UNION ALL SELECT DATE '2019-07-26','B','alpha'
UNION ALL SELECT DATE '2019-08-01','A','y'
UNION ALL SELECT DATE '2019-08-01','B','beta'
UNION ALL SELECT DATE '2019-08-03','A','z'
UNION ALL SELECT DATE '2019-08-03','B','gamma'
)
-- real WITH clause would start here ...                                                                                                                                                 
,
-- newest row per Url, just with current date
pad_newest AS (
SELECT
  CURRENT_DATE
, url 
, score
FROM score_upd
LIMIT 1 OVER(PARTITION BY url ORDER BY upd_dt DESC)
)   
,   
with_newest AS (
SELECT
  *   
FROM score_upd
UNION ALL 
SELECT *
FROM pad_newest
)   
SELECT
  ts_dt::DATE           AS upd_dt
, url                   AS url 
, TS_FIRST_VALUE(score) AS score
FROM with_newest
TIMESERIES ts_dt AS '1 day' OVER (
  PARTITION BY url ORDER BY upd_dt::TIMESTAMP
)   
ORDER BY 1,2 
;   
...