Сокращение серии дат до минимального представления в BigQuery - PullRequest
0 голосов
/ 16 октября 2018

Если у меня есть таблица типа:

start_date|end_date
1/1/2018|1/5/2018
1/4/2018|1/10/2018
1/9/2018|1/22/2018
2/1/2018|2/1/2018
1/31/2018|2/5/2018

И я хочу получить все диапазоны дат, охватываемые этими строками.Поэтому я бы хотел, чтобы что-то возвращалось, например:

1/1/2018|1/22/2018
1/31/2018|2/5/2018

Есть ли в BigQuery функция, которая может справиться с этим?

1 Ответ

0 голосов
/ 17 октября 2018

Такой функции нет - но вы можете попробовать что-то вроде ниже (BigQuery Standard SQL)

#standardSQL
WITH `project.dataset.table` AS (
  SELECT '1/1/2018' start_date, '1/5/2018' end_date UNION ALL
  SELECT '1/4/2018', '1/10/2018' UNION ALL
  SELECT '1/9/2018', '1/22/2018' UNION ALL
  SELECT '2/1/2018', '2/1/2018' UNION ALL
  SELECT '1/31/2018', '2/5/2018' 
), parsed_as_dates AS (
  SELECT PARSE_DATE('%m/%d/%Y', start_date) start_date, PARSE_DATE('%m/%d/%Y', end_date) end_date
  FROM `project.dataset.table`
), days AS (
  SELECT day FROM 
  (SELECT MIN(start_date) min_date, MAX(end_date) max_date FROM parsed_as_dates), 
  UNNEST(GENERATE_DATE_ARRAY(min_date, max_date)) day
), temp AS (
  SELECT day, SIGN(COUNTIF(day BETWEEN start_date AND end_date)) flag
  FROM days CROSS JOIN parsed_as_dates GROUP BY day
)
SELECT MIN(day) start_date, MAX(day) end_date
FROM (
  SELECT day, flag, SUM(start) OVER(ORDER BY day) grp
  FROM (
    SELECT day, flag, ABS(flag - IFNULL(LAG(flag) OVER(ORDER BY day), 0)) start
    FROM temp
  )
)
WHERE flag = 1
GROUP BY grp
-- ORDER BY start_date

с результатом ниже

Row start_date  end_date     
1   2018-01-01  2018-01-22   
2   2018-01-31  2018-02-05    

Просто "быстрая" идея - вы можетеЯ хочу немного изменить его, так как он выглядит немного перегруженным: o) но, по крайней мере, он работает

...