我正在弄乱一个测试数据库表结构来存储事件重复发生。我有两个桌子:
课程
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)多次显示一行。我确实进行了搜索并找到了一些信息,但到目前为止没有任何帮助。甚至不确定这是否是存储此信息的最佳方法。
答案 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 |