Нахождение даты начала нового проекта - PullRequest
0 голосов
/ 08 декабря 2018

Заинтересован в сложной проблеме SQL, читайте заранее:

Для данных, приведенных ниже, я пытаюсь найти логику, которая идентифицирует дату начала нового проекта для каждого сотрудника.

Набор данных

enter image description here

Логика для определения даты начала нового проекта такова:

  1. У сотрудника не будет записи о дате до текущей даты в 14-дневном периоде.

  2. Окна проекта только для последних 14 дней после начала,Первая запись, выходящая за пределы такого окна, будет считаться началом следующего проекта.

Что необходимо

enter image description here

Оба решения Redshift / Postgres приняты.

Обратите внимание Redshift не поддерживает рекурсивные CTE или ключевое слово RANGE в рамке окна.

Спасибо за чтение.

1 Ответ

0 голосов
/ 09 декабря 2018

Для Postgresql, включая CTE (DataSet) для набора данных, вы идете:

WITH RECURSIVE TimeLine(Employee, ProjectID, ProjectStartDate, Date, DateRank) AS (
    SELECT Employee, 1, Date, Date, DateRank
    FROM DataSetWithRank
    WHERE DateRank = 1
    UNION ALL
    SELECT T.Employee,
           T.ProjectID + CASE When D.Date >= T.ProjectStartDate+14 THEN 1 Else 0 END,
           CASE When D.Date >= T.ProjectStartDate+14 THEN D.Date Else T.ProjectStartDate END,
           D.Date, D.DateRank
    FROM TimeLine T
    JOIN DataSetWithRank D ON D.Employee = T.Employee AND D.DateRank = T.DateRank + 1
), DataSet(Employee,Date) AS (
SELECT UNNEST(ARRAY['Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1','Employee1']),
    UNNEST(ARRAY['2018-01-01','2018-01-03','2018-01-05','2018-01-08','2018-01-11','2018-01-13','2018-01-14','2018-01-16','2018-01-18','2018-01-21','2018-01-22','2018-01-24','2018-01-25','2018-01-27','2018-01-29']::date[])
UNION
SELECT UNNEST(ARRAY['Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2','Employee2']),
    UNNEST(ARRAY['2018-01-03','2018-01-05','2018-01-07','2018-01-10','2018-01-13','2018-01-15','2018-01-16','2018-01-18','2018-01-20','2018-01-23','2018-01-24','2018-01-26','2018-01-27','2018-01-29','2018-01-31']::date[])
), DataSetWithRank AS (
SELECT *, DENSE_RANK() OVER (PARTITION BY Employee ORDER BY Date) AS DateRank
FROM DataSet
)
SELECT Employee,
       'Project ' || ProjectID AS "Project #",
       Date,
       DENSE_RANK() OVER (PARTITION BY Employee, ProjectID ORDER BY Date) AS Rank,
       CASE WHEN Date = ProjectStartDate THEN 'Y' ELSE NULL END AS Is_New
FROM TimeLine
...