基于SQL Server中某列的聚合,从单个记录生成多个记录



我想根据单个记录中的列计算生成多行

示例

client   reminder_date   day   generate_reminder
------------------------------------------------
a        2021-10-01      28            4

在上面的例子中,generate_ereminder是4,day是28。所以我想每28天生成4条提醒记录。

这是我需要的输出:

client   reminder_date 
----------------------
a       2021-10-01      
a       2021-10-29 
a       2021-11-25
a       2021-12-23

一种方法是使用Tally生成足够的行以JOIN到,然后将Tally Number乘以天数,并将其添加到第一个提醒日期:

WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT 0 AS I
UNION ALL
SELECT TOP (SELECT MAX(GenerateReminder)-1 FROM dbo.YourTable)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2) --100 rows Add more cross joins for more rows
SELECT YT.Client,
DATEADD(DAY,[Day] * T.I,YT.ReminderDate) AS ReminderDate
FROM dbo.YourTable YT
JOIN Tally T ON YT.GenerateReminder > T.I;

请注意,结果与您的问题不匹配,因为2021-10-29+28天是2021-11-26,而不是2021-11-25。

db<gt;小提琴

尝试一个简单的递归CTE

CREATE TABLE #Temp
(
CLient VARCHAR(20),
Reminder_date DATE,
Day INT,
generate_reminder int
)
INSERT INTO #Temp
VALUES('A','20201-10-01',28,4)

;WITH CTE
AS
(
SELECT
Client,
Reminder_date,
Day,
generate_reminder
FROM #TEMP
UNION ALL
SELECT
Client,
Reminder_date = DATEADD(DAY,Day,Reminder_date),
Day,
generate_reminder = ISNULL(generate_reminder,0)-1
FROM CTE
WHERE generate_reminder >1

)
SELECT
Client,
Reminder_date
FROM CTE

这是小提琴的链接

http://sqlfiddle.com/#!18/18da09/4

这是一种紧凑的方法,尤其是在提醒次数有合理上限的情况下。

select a, dateadd(day, increment, reminder_date) as reminder_date
from tableX t cross apply (
select n * "day" from (values (0), (1), (2), (3), (4), (5)) as v(n)
) ca(increment)
where n < t.generate_reminder;