如何为不同的日期出现返回同一行

时间:2018-07-21 14:31:37

标签: sql sql-server date sql-server-2012

我正在弄乱一个测试数据库表结构来存储事件重复发生。我有两个桌子:

课程

Id          = 1
Title       = Test Course

课程元

Id          = 1
CourseId    = 1
StartDate   = 2018-01-01
RepeatEvery = 7
RepeatAmount = 4

假设上面的值,我试图生成的(在单个SQL行中)是该日期范围内每个日期的课程列表,从 2018-01-01 开始,每次 7 天,直到进行了 4 次迭代。例如,我需要以下输出:

Title        Date
-----------  ----------
Test Course  2018-01-01
Test Course  2018-01-08
Test Course  2018-01-15
Test Course  2018-01-22

我被困住了,因为我不知道如何根据条件使MS SQL(2012)多次显示一行。我确实进行了搜索并找到了一些信息,但到目前为止没有任何帮助。甚至不确定这是否是存储此信息的最佳方法。

2 个答案:

答案 0 :(得分:1)

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

var publicKey = "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiHpDUH0AtBRNvqEblOeVyviJZ 4UV2LwGiWrSIysK4sL3mToAgDz11MWvo+yycMmwjCiFAQgF4vspzTAexJ6+ZIvbi WRGdJiaqqja2xMRZkDJuJF2rN5CrbNhKrmyM1+weud2jhIHXdxkbJb89oRrbOvfh yWuY8J7pPFiTnzH9sQIDAQAB -----END PUBLIC KEY-----";

                var key =
                    "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiHpDUH0AtBRNvqEblOeVyviJZ 4UV2LwGiWrSIysK4sL3mToAgDz11MWvo+yycMmwjCiFAQgF4vspzTAexJ6+ZIvbi WRGdJiaqqja2xMRZkDJuJF2rN5CrbNhKrmyM1+weud2jhIHXdxkbJb89oRrbOvfh yWuY8J7pPFiTnzH9sQIDAQAB";

                var token = "eyJraWQiOiIwZTIwZjU0NC00ZmQzLTQ4YTYtOGUzMi01NWUwNTJiMDI2ODIiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJzdWJqZWN0IiwiYXVkIjoiYXVkaWVuY2UxIiwibWVtYmVySW5mbyI6eyJNZW1iZXJzaGlwTnVtYmVycyI6WyIwMzUzNzUzMjkwIiwiMDM4MTQxMDI1OCJdLCJMaWZldGltZUlkcyI6WyIzMzUzNzUzMjkwMDEiXSwiQm9zc0lkcyI6WyIxMjM0NTY3OCIsIjE2NTI0MTUyIiwiMTg5OTEyMzQiXSwiQ2hlZXJzSWRzIjpbIjU2NzgxMjM0Il0sIlVzZXJDb250ZXh0IjoiR0JCVVBBR1JPVVBcXFNWQ19zd2lmdHdlYnRlc3QiLCJSZXF1ZXN0UGFyYW1ldGVycyI6bnVsbH0sImlzcyI6Imh0dHBzOi8vYnVwYWRldi1xYS5hcGlnZWUubmV0IiwiZXhwIjoxNTMyMjA2NDc1LCJpYXQiOjE1MzIxNzc2NzUsImp0aSI6IjZlOThmOTU2LTdlZTUtNGQxYy1iN2M4LWUwNGNlNzlkZjZjZSJ9.jC7-bVSaxAGNLk2d--8fksH_9PKgo3TgIALynlwkUOC3AE79MrLaqCRGp0yT2wqfFJ5kRGJFyUu_EP3_3YE6d4XS5yhghaFrkewwUHt4eV56qYOFf4RIC_CiX_OcK8vXSEpeMt6jKN-f7iDP6fo2NqmYH07_ZJM0LXc7S5WAQDQ";

                var certificate = new X509Certificate2(Convert.FromBase64String(key));
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningTokens = new[] { new X509SecurityToken(certificate) }
                };
                SecurityToken validatedSecurityToken = null;
                var handler = new JwtSecurityTokenHandler();
                try
                {
                    handler.ValidateToken(token, validationParameters, out validatedSecurityToken);
                }
                catch (Exception ex)
                {

                }

要获取名称,您需要添加最后一个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;

注意:如果JOIN超过100,则添加repeatamount

答案 1 :(得分:1)

如果您有数字表,可以执行此操作(使用master..spt_values作为数字表):

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

结果:

| id | title       | (No column name)        |
|----|-------------|-------------------------|
| 1  | test course | 2018-01-01 00:00:00.000 |
| 1  | test course | 2018-01-08 00:00:00.000 |
| 1  | test course | 2018-01-15 00:00:00.000 |
| 1  | test course | 2018-01-22 00:00:00.000 |