Определите острова с иерархией, датами начала и окончания в Cloudera 6.2x Impala - PullRequest
0 голосов
/ 05 июля 2019

У меня есть хитрая проблема с пропусками и островами. Острова дат должны быть идентифицированы в иерархии полей.

Эта проблема пробелов и островков отличается от традиционного типа в нескольких отношениях:

  1. Даты представлены в формате диапазона в двух полях (StartDate и EndDate)
  2. Группировка островов должна учитывать иерархию полей
  3. Эти данные содержатся в Cloudera 6.2x, который ограничивает некоторые потенциальные решения (например, рекурсивный cte)

Если конечная дата иерархии находится в тот же день или день до начальной даты следующего вхождения, это должен быть остров. Как я могу сделать это, учитывая мои ограничения и пример данных?

Я попытался найти несколько решений, включая следующий псевдокод:

  1. создать row_number над разделом полей иерархии, упорядоченным по этим иерархиям и StartDate.

  2. определить пробелы с помощью логики регистра когда days_add (end_date, 1)> = lead (start_date, 1) и row_number

  3. идентифицировать острова с помощью логики регистра: когда row_number = 1, то 1 когда лаг (пробелы, 1) = 1, то лаг (острова, 1) + 1 остальное отставание (острова, 1)

Это должно логически работать для создания островков, которые я могу использовать для группировки и получения минимума startDate и максимума EndDate, сгруппированных по иерархии. Когда я ставлю данные в Excel и применяю этот алгоритм, я получаю правильные результаты. По-видимому, в Cloudera нет оценки лагов (островов, 1) при оценке каждой записи?

CREATE TABLE sampleInput (
  person int, 
  level1 int, 
  level2 int, 
  level3 int, 
  StartDate DATETIME, 
  EndDate DATETIME,
  rowNumber int)

INSERT INTO sampleInput
VALUES
(1,1,17,101,'2001-09-16','2001-09-19',1),
(1,1,17,102,'2001-09-20','2001-09-24',2),
(1,1,17,103,'2001-04-15','2001-04-25',3),
(1,1,17,104,'2001-08-02','2001-08-15',4),
(1,1,20,105,'2001-03-10','2001-03-18',5),
(1,1,20,105,'2001-04-01','2001-04-08',6),
(1,1,20,105,'2001-07-20','2001-07-25',7),
(1,1,20,106,'2001-02-20','2001-02-08',8),
(1,1,31,107,'2001-04-25','2001-04-30',9),
(1,1,31,107,'2001-05-01','2001-05-29',10),
(2,3,42,111,'2002-04-05','2002-04-05',11),
(2,3,42,111,'2002-04-06','2002-04-06',12),
(2,3,42,111,'2002-04-07','2002-04-30',13),
(2,3,42,111,'2002-05-01','2002-05-25',14),
(2,3,42,111,'2002-05-28','2002-06-01',15),
(2,3,42,111,'2002-06-04','2002-06-06',16),
(2,3,42,111,'2002-06-08','2002-06-20',17)

И

CREATE TABLE sampleOutput (
  person int, level1 int, level2 int, level3 int, 
  StartDate DATETIME, EndDate DATETIME ,rowNumberConcat varchar(max)
)

INSERT INTO sampleOutput
VALUES
(1,1,17,101,'2001-09-16','2001-09-19','1'),
(1,1,17,102,'2001-09-20','2001-09-24','2'),
(1,1,17,103,'2001-04-15','2001-04-25','3'),
(1,1,17,104,'2001-08-02','2001-08-15','4'),
(1,1,20,105,'2001-03-10','2001-03-18','5'),
(1,1,20,105,'2001-04-01','2001-04-08','6'),
(1,1,20,105,'2001-07-20','2001-07-25','7'),
(1,1,20,106,'2001-02-20','2001-02-08','/'),
(1,1,31,107,'2001-04-25','2001-05-29','9,10'),
(2,3,42,111,'2002-04-05','2002-05-25','11,12,13,14'),
(2,3,42,111,'2002-05-28','2002-06-01','15'),
(2,3,42,111,'2002-06-04','2002-06-06','16'),
(2,3,42,111,'2002-06-08','2002-06-20','17')

Я включил ввод и вывод в следующую скрипту SQL: http://www.sqlfiddle.com/#!18/770768/1 Включенные поля rowNumber и rowNumberConcat включены только для отображения происхождения входных и выходных данных. Скрипка настроена для MSSQL только потому, что нет опции Cloudera. В качестве примечания: если бы я использовал другой аромат или совершенно другой сайт, пожалуйста, дайте мне знать.

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