使用SQL预测将来的约会

时间:2019-07-02 16:01:23

标签: sql sql-server

我希望你们中的任何人都可以帮助解决以下SQL问题,我正在寻找一种预测SQL中将来约会的方法。

例如,我有一个项目编号为“ P01155220”(请参见下面的示例表),其中已有一些约会(请参见约会约会列)。我正在尝试完成以下任务:

  • 下一次(虚拟)约会将是最后的约会日期+ 42天。例如,下一个约会日期将是2019-06-27 + 42天= 2019-08-08。
  • 只要running_total <450天,此+42天的预测应继续添加“行”。

“预测”下一个即将到来的约会日期的最佳方法是什么?

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 :(得分:0)

有很多方法可以解决它,这就是我的方法。我并不是说这是最好的方法,但是它与您的输出匹配。如果您不需要运行总计,则第二个查询要简单得多。

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