Прогноз будущих встреч с использованием SQL - PullRequest
0 голосов
/ 02 июля 2019

Я надеюсь, что любой из вас может помочь мне решить следующую проблему с SQL. Я ищу способ предсказать будущие встречи в SQL.

Например, у меня есть номер проекта "P01155220" (см. Пример таблицы ниже), в котором были некоторые встречи (см. Столбец встречи_дата). Я пытаюсь сделать следующее:

  • Следующая (виртуальная) встреча будет последней датой встречи + 42 дня. Например, следующая дата встречи будет 2019-06-27 + 42 дня = 2019-08-08.
  • Это предсказание +42 дня должно продолжать добавлять «строки», пока running_total <450 дней. </li>

Каков наилучший способ «предсказать» даты следующей предстоящей встречи?

unique_id   appointment_date    days_between    Running_total
P01155220   2018-11-19          0               0
P01155220   2019-01-17          59              59
P01155220   2019-03-21          63              122
P01155220   2019-06-27          98              220

Простой запрос;

SELECT
    unique_id
    ,appointment_date
    ,days_between
    ,SUM(days_between) OVER(ORDER BY unique_id,appointment_date) AS Running_total
  FROM [records]

Вывод таблицы, которую я ожидаю, должен выглядеть следующим образом:

    |Unique_id|Appointment_date|Days_between|Running_total|
|P0115220|2018-11-19|0|0|
|P0115220|2019-01-17|59|59|
|P0115220|2019-03-21|63|122|
|P0115220|2019-06-27|98|229|
|P0115220|2019-06-27+42|42|271|
|P0115220|2019-06-27+42+42|42|313|
|P0115220|2019-06-27+42+42+42|42|355|
|P0115220|2019-06-27+42+42+42+42|42|397|
|P0115220|2019-06-27+42+42+42+42+42|42|439|

1 Ответ

0 голосов
/ 04 июля 2019

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

CREATE TABLE #data(Date date)
INSERT INTO #data VALUES('11/19/2018')
INSERT INTO #data VALUES('1/17/2019')
INSERT INTO #data VALUES('3/21/2019')
INSERT INTO #data VALUES('6/27/2019')

;
WITH
dates
AS (SELECT Date, Elapsed = DATEDIFF(dd, ISNULL(LAG(Date) OVER (ORDER BY Date), Date), Date) FROM #data),
run
AS  (SELECT Date, RunningTotal = SUM(Elapsed) OVER (ORDER BY Date ROWS UNBOUNDED PRECEDING) FROM dates  )
SELECT * FROM run
UNION ALL
SELECT  date = DATEADD(dd, 42 * t1.number, l.lastdate),
    RunningTotal = l.RunningTotal + t1.number * 42
FROM    master..spt_values t1
    OUTER APPLY (SELECT lastdate = MAX(Date), RunningTotal = MAX(RunningTotal) FROM run) l
WHERE
    type = 'p'
    AND t1.number > 0
    AND l.RunningTotal + t1.number * 42 < 450

--------
SELECT d.Date
FROM #data d
UNION ALL
SELECT  date = DATEADD(dd, 42 * t1.number, l.lastdate)
FROM    master..spt_values t1
    OUTER APPLY (SELECT firstDate = MIN(date),lastdate = MAX(Date) FROM #data) l
WHERE
    type = 'p'
    AND t1.number > 0
    AND DATEDIFF(dd,l.firstDate,lastdate) + t1.number * 42 < 450
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...