动态日期 SQL 服务器

Dynamic Dates SQL Server

我在 SQL 中有以下数据。

我需要想出一种方法来根据下面的 2 个值动态获取下一个日期。剩余剂量告诉我需要查找多少日期,RXDAYS 告诉我查找日期的增量

Date Shipped    Remaining Doses RXDAYS
2019-06-05      2               30

所以根据上面的内容,我会找到 2019-06-05 后 30 天的日期,得到 2019-07-05,再过 30 天,我会得到 2019-08-04。

有办法吗?

使用dateadd()。这为您提供了最终日期:

dateadd(day, doses * rxdays, date_shipped)

另一方面,如果您想生成新行,则可以使用递归查询:

with cte as (
    select date_shipped mydate, doses, rxdays from mytable
    union all
    select (dateadd(day, rxdays, date_shipped), doses - 1, rxdays 
    from cte
    where doses > 0
)
select mydate from cte

对于您问题中显示的示例数据行,这将生成三行,日期为 2019-06-052019-07-052019-08-04

如果 doses 的值大于 100,那么您需要在查询的最后添加 option(maxrecursion 0)

您可以使用DATEADD()函数作为

SELECT *, CONVERT(DATE, DATEADD(Day, RXDAYS, DateShipped)) FirstDateToFind,
          CONVERT(DATE, DATEADD(Day, RXDAYS * 2, DateShipped)) SecondDateToFind
FROM
(
  VALUES
  ('2019-06-05',      2,               30)
) T(DateShipped, RemainingDoses, RXDAYS);

更新:

您似乎正在寻找生成如下行的行:

WITH Data AS
(
  SELECT *
  FROM T
  UNION ALL
  SELECT CONVERT(DATE, DATEADD(Day, (RXDAYS * (RemainingDoses - RemainingDoses + 1)), DateShipped)),
         RemainingDoses - 1,
         RXDAYS
  FROM Data
  WHERE RemainingDoses > 0
)
SELECT *
FROM Data
ORDER BY DateShipped;

这是一个db<>fiddle

另一种方法是使用数字 table(如果您还没有数字,也可以即时创建自己的数字)。假设您不能提供超过 255 剂:

DECLARE @Doses table 
(
    RowID          int IDENTITY(1,1),
    DateShipped    date,
    RemainingDoses tinyint,
    RXDays         tinyint
);

INSERT @Doses(DateShipped, RemainingDoses, RXDays)
  VALUES('20190605',2,30),('20190704',3,24);

-- pseudo Numbers table
DECLARE @num table(n tinyint);

INSERT @num(n) SELECT TOP (256) 
       row_number() OVER (ORDER BY (SELECT NULL)) - 1 
  FROM sys.all_columns;


SELECT d.RowID, d.DateShipped, d.RemainingDoses, d.RXDays,
    SubsequentShipdate = DATEADD(DAY, n.n*d.RXDays, d.DateShipped) 
  FROM @Doses AS d
  INNER JOIN @num AS n
  ON n.n <= d.RemainingDoses
  ORDER BY d.RowID, SubsequentShipdate;

结果:

如果您只想要 "next" 日期而不包括原始行,只需添加:

AND n.n > 0

或者,不要在数字 table 中包含 0(尽管它 可以 有用):

INSERT @num(n) SELECT TOP (255) 
       row_number() OVER (ORDER BY (SELECT NULL))