SQL - Попытка создать ежедневный журнал, присоединившись к таблице измерений даты - PullRequest
0 голосов
/ 17 апреля 2020

Как правильно присоединиться к таблице измерений даты, чтобы создать представление ежедневного журнала в Snowflake.

Это то, что я пытаюсь создать

WITH testing AS (
SELECT 
  21374884 AS projectid,
  '2020-04-01'::DATE AS createdat,
  'LIVE' AS Status
UNION ALL
  SELECT 21374884 AS projectid,
  '2020-04-10'::DATE AS createdat,
  'COMPLETE' AS Status
  UNION ALL
  SELECT 
  1111111 AS projectid,
  '2020-04-01'::DATE AS createdat,
  'LIVE' AS Status
UNION ALL
  SELECT 1111111 AS projectid,
  '2020-04-10'::DATE AS createdat,
  'COMPLETE' AS Status
  )

, что создает

PROJECTID   CREATEDAT   STATUS
21374884    2020-04-01  LIVE
21374884    2020-04-10  COMPLETE
1111111     2020-04-01  LIVE
1111111     2020-04-10  COMPLETE
 

Я хотел бы присоединиться к моему date_dim , чтобы это выглядело так, если бы я вытащил дневной статус с 4-1-2020 до 4-15-2020.

PROJECTID   CREATEDAT   STATUS
21374884    2020-04-01  LIVE
21374884    2020-04-02  LIVE
21374884    2020-04-03  LIVE
21374884    2020-04-04  LIVE
21374884    2020-04-05  LIVE
etc...
21374884    2020-04-10  COMPLETE
21374884    2020-04-11  COMPLETE
21374884    2020-04-12  COMPLETE
21374884    2020-04-13  COMPLETE
21374884    2020-04-14  COMPLETE
21374884    2020-04-15  COMPLETE
1111111     2020-04-01  LIVE
1111111     2020-04-02  LIVE
1111111     2020-04-03  LIVE
1111111     2020-04-04  LIVE
etc..
1111111     2020-04-10  COMPLETE
1111111     2020-04-11  COMPLETE
1111111     2020-04-12  COMPLETE
1111111     2020-04-13  COMPLETE
1111111     2020-04-14  COMPLETE
1111111     2020-04-15  COMPLETE
....
 

Ответы [ 2 ]

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

Если мы предположим, что у нас есть таблица измерения даты, определенная и заполненная как:

CREATE OR REPLACE TEMPORARY TABLE date_dim (
  the_date  DATE
)
AS
  SELECT DATEADD(DAY, SEQ8(), '2020-03-01'::DATE) AS the_date
    FROM TABLE(GENERATOR(ROWCOUNT => 100))  -- assume a 100 row date dim table
;

, а другая таблица данных, определенная и заполненная как:

CREATE OR REPLACE TEMPORARY TABLE testing (
  projectid  INTEGER
 ,createdat  DATE
 ,status     VARCHAR
)
AS
  SELECT $1 AS projectid
        ,$2::DATE AS createdat
        ,$3 AS status
    FROM VALUES
           (21374884, '2020-04-01', 'LIVE')
          ,(21374884, '2020-04-10', 'COMPLETE')
          ,(1111111, '2020-04-01', 'LIVE')
          ,(1111111, '2020-04-10', 'COMPLETE')
;

, то мы можем создать результат, который вы ищете с этим:

WITH cte_x AS (
  SELECT projectid
        ,createdat
        ,LEAD(createdat) OVER (PARTITION BY projectid ORDER BY createdat) AS nextdat
        ,status
    FROM testing t
)
SELECT cte_x.projectid
      ,dd.the_date AS createdat
      ,cte_x.status
  FROM cte_x
       JOIN date_dim dd
         ON dd.the_date >= cte_x.createdat
        AND (cte_x.nextdat IS NULL OR dd.the_date < cte_x.nextdat)
 WHERE dd.the_date BETWEEN '2020-04-01'::DATE AND '2020-04-15'::DATE
 ORDER BY 1,2
;
0 голосов
/ 17 апреля 2020

В стандартном SQL вы должны использовать lag(ignore nulls):

select p.projectid, d.date,
       coalesce(t.status,
                lag(t.status ignore nulls) over (partition by p.projectid, d.date)
               ) as status
from (select distinct projectid from testing) p join
     date_dim d
     on d.date between '2020-04-01' and '2020-04-15' left join
     testing t
     on t.createdat = d.date and t.projectid = p.projectid;

Не все базы данных поддерживают lag(ignore nulls), но вы не указали базу данных, и это стандарт SQL.

...