【发布时间】:2017-09-22 19:19:36
【问题描述】:
我不知道我在哪里搞砸了。完整代码:
DECLARE @start_date DATETIME, @end_date DATETIME
DECLARE @Table TABLE (StartDate DATETIME, Enddate DATETIME, WeekNo INT)
SET @start_date = '2017-01-01'
SET @end_date = '2017-12-31'
INSERT INTO @Table
SELECT
MIN(dt), MAX(dt), w
FROM
(SELECT
dt, year(dt) y, DATEPART(week, dt) w
FROM
(SELECT
@start_date + (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) dt
FROM
sys.columns s1
CROSS JOIN
sys.columns s2) q
WHERE
dt BETWEEN @start_date AND @end_date) a
GROUP BY
y, w
我已经缩小了错误发生的范围。它发生在这里:
SELECT
dt, year(dt) y, DATEPART(week, dt) w
FROM
(SELECT
@start_date + (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) dt
FROM
sys.columns s1
CROSS JOIN
sys.columns s2) q
WHERE
dt BETWEEN @start_date AND @end_date
如果我只运行这部分,我会收到错误:
将表达式转换为数据类型日期时间时出现算术溢出错误。
我尝试在这里和那里添加一些CONVERT 试图找出它在哪里搞砸了,但我无法弄清楚。
我见过其他几个人遇到类似问题,但this one 或this one 都没有任何对我有帮助的解决方案。
我是基于集合的 SQL 编程的新手,我是循环自学的,所以这超出了我的深度。任何帮助表示赞赏。
【问题讨论】:
-
您希望
@start_date + (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1)增加一天吗? -
@scsimon 确实如此。如果我只运行那个内部选择,我会得到一年中每一天的列表,从
@Start_Date开始,一直持续到我停止查询。 -
我知道它的作用,我在问你是否期望它。它不适用于日期,但可以在
datetime上使用,但出于明确的原因和代码管理,我建议坚持使用dateadd()。很多人滥用这个。 -
我运行了您的代码,并提供了一个指向上述在线版本的链接,因此使用该 sn-p 它是不可重现的。语法为
dateadd(day, (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1),@start_date),因为您似乎需要表格中的 RN -
尝试并测试它的不同部分。为
@start_date + DATEADD(day, 1, @start_date的每个部分执行单独的select语句。显然,第一部分将只显示@start_date is,但第二部分是做什么的?您正在尝试为其添加一天,然后当前将其添加回自身。此外,您知道问题出在哪里,并且您也知道问题出在哪里(在select语句中)。摆脱where子句,是否摆脱它?不?将select替换为select *。现在怎么样?代码很小,所以摆脱或隔离找到它。
标签: sql-server datetime