Sql 如何为不同的日期事件返回同一行

Sql 如何为不同的日期事件返回同一行,sql,sql-server,date,sql-server-2012,Sql,Sql Server,Date,Sql Server 2012,我正在处理一个测试数据库表结构来存储具有重复性的事件。我有两张桌子: 课程 CourseMeta 假设上述值,我试图在单个SQL行中生成范围内每个日期的课程列表,从2018-01-01开始,每7天一次,直到有4次迭代。例如,我正在查找以下输出: 所有权日期 ------ ----- 考试课程2018-01-01 考试课程2018-01-08 考试课程2018-01-15 考试课程2018-01-22 我被卡住了,因为我不知道如何让MS SQL 2012根据条件多次显示一行。我确实搜索了一下,找

我正在处理一个测试数据库表结构来存储具有重复性的事件。我有两张桌子:

课程

CourseMeta

假设上述值,我试图在单个SQL行中生成范围内每个日期的课程列表,从2018-01-01开始,每7天一次,直到有4次迭代。例如,我正在查找以下输出:

所有权日期 ------ ----- 考试课程2018-01-01 考试课程2018-01-08 考试课程2018-01-15 考试课程2018-01-22
我被卡住了,因为我不知道如何让MS SQL 2012根据条件多次显示一行。我确实搜索了一下,找到了一些信息,但到目前为止没有任何帮助。甚至不确定这是否是存储此信息的最佳方式。

您可以使用递归CTE生成行:

with cte as (
      select courseid, startdate, repeatevery, repeatamount, 1 as cnt
      from coursemeta
      union all
      select courseid, dateadd(day, repeatevery, startdate), repeatevery, repeatamount, cnt + 1
      from cte
      where cnt < repeatamount
     )
select courseid, startdate
from cte;
要获得名称,您需要添加一个最终联接


注意:如果repeatamount超过100,请使用选项maxrecursion 0添加。

您可以使用递归CTE生成行:

with cte as (
      select courseid, startdate, repeatevery, repeatamount, 1 as cnt
      from coursemeta
      union all
      select courseid, dateadd(day, repeatevery, startdate), repeatevery, repeatamount, cnt + 1
      from cte
      where cnt < repeatamount
     )
select courseid, startdate
from cte;
要获得名称,您需要添加一个最终联接


注意:如果repeatamount超过100,请使用选项maxrecursion 0进行添加。

如果您有数字表,则可以使用master..spt_值作为数字表:

WITH course(id, title) AS (
    SELECT 1, 'test course'
), coursemeta(courseid , startdate, repeatevery, repeatamount) AS (
    SELECT 1, '2018-01-01', 7, 4
), numbers(number) AS (
    SELECT number FROM master..spt_values WHERE type = 'p'
)
SELECT id, title, DATEADD(day, numbers.number * repeatevery, startdate)
FROM course
INNER JOIN coursemeta ON course.id = coursemeta.courseid
INNER JOIN numbers ON numbers.number < coursemeta.repeatamount

如果您有一个数字表,则可以使用master..spt_值作为数字表:

WITH course(id, title) AS (
    SELECT 1, 'test course'
), coursemeta(courseid , startdate, repeatevery, repeatamount) AS (
    SELECT 1, '2018-01-01', 7, 4
), numbers(number) AS (
    SELECT number FROM master..spt_values WHERE type = 'p'
)
SELECT id, title, DATEADD(day, numbers.number * repeatevery, startdate)
FROM course
INNER JOIN coursemeta ON course.id = coursemeta.courseid
INNER JOIN numbers ON numbers.number < coursemeta.repeatamount

实际问题比我发布的要复杂一些,但是我发现这非常有用。实际问题比我发布的要复杂一些,但是我发现这非常有用。