考虑在日期上创建带有递归CTE的日历。但是,一旦运行它,我将收到以下错误:
递归查询“ cte_days”的列“ ddmmyyyy”中的锚点与递归部分之间的类型不匹配
代码:
WITH cte_days(n, weekd, ddmmyyyy) AS
(
SELECT
0, DATENAME(DW, '09-03-1983'), CONVERT(varchar, '09-03-1983', 10)
UNION ALL
SELECT
0 + 1, DATENAME(weekday, DATEADD(day, 1, '09-03-1983')), DATEADD(day, 1, '09-03-1983')
FROM
cte_days
WHERE
n < 10
)
SELECT *
FROM cte_days
那时,我尝试在ddmmyyyy
列中测试数据,该数据在中间运行两个SELECTS并被正确返回:
0 Saturday 1983-09-03 00:00:00.000
1 Sunday 1983-09-04 00:00:00.000
使用日期列创建临时表并将两个值都粘贴在其中后,它也可以正常工作。
那么您可以帮助查找不匹配的内容吗?
谢谢。
答案 0 :(得分:3)
“考虑在日期上创建带有递归CTE的日历。” 老实说,我建议在rCTE上使用Tally。 rCTE实际上比Tally慢得多。这应该足以让您入门:
DECLARE @StartDate date = '19830309';
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT TOP (100) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1, N N2, N N3) --Add more Cartisian Joins and increase value of TOP to get more rows
SELECT I,
DATENAME(WEEKDAY,DATEADD(DAY, I, @StartDate)) AS DayName,
DATEADD(DAY, I, @StartDate) AS DyDate
FROM Tally;
答案 1 :(得分:1)
SQL Server对字符串类型很挑剔。但我建议您将注意力集中在CTE中的日期上,然后再进行转换:
WITH cte_days(n, dte) AS (
SELECT 0, CONVERT(date, '19830309')
UNION ALL
SELECT n+1, DATEADD(day, 1, dte)
FROM cte_days
WHERE n < 10
)
SELECT n, DATENAME(weekday, dte), CONVERT(VARCHAR(255), dte, 10)
FROM cte_days;
答案 2 :(得分:0)
使用CAST函数代替CONVERT也有帮助:
WITH cte_days(n, weekd, ddmmyyyy)
AS (
SELECT 0, DATENAME(DW, '09-03-1983'),CAST(CAST('09-03-1983' AS DATE) AS DATETIME)
UNION ALL
SELECT n+1, DATENAME(weekday, DATEADD(day, 1, '09-03-1983')), DATEADD(day, 1, '09-03-1983')
FROM cte_days
WHERE n < 10
)
SELECT * FROM cte_days
答案 3 :(得分:0)
将“从n <10开始的cte_days天数”移到CTE之外是可以的。
--Your Code:
WITH cte_days(n, weekd, ddmmyyyy) AS
(
SELECT
0, DATENAME(DW, '09-03-1983'), CONVERT(varchar, '09-03-1983', 10)
UNION ALL
SELECT
0 + 1, DATENAME(weekday, DATEADD(day, 1, '09-03-1983')), DATEADD(day, 1, '09-03-1983')
FROM
cte_days
WHERE
n < 10
)
SELECT *
FROM cte_days
工作代码:
WITH cte_days(n, weekd, ddmmyyyy) AS
(
SELECT
0, DATENAME(DW, '09-03-1983'), CONVERT(varchar, '09-03-1983', 10)
UNION ALL
SELECT
0 + 1, DATENAME(weekday, DATEADD(day, 1, '09-03-1983')), DATEADD(day, 1, '09-03-1983')
)
SELECT *
FROM cte_days
WHERE
n < 10
以上返回以下结果:
n weekd ddmmyyyy
0 Saturday 1983-09-03 00:00:00.000
1 Sunday 1983-09-04 00:00:00.000