我需要返回过去30天内的总和。我的日期字段是一个文本字段。我的桌子看起来像这样:
Client Serial# Hrs MyDate
A 1 12 20200501
A 1 8 20200513
B 5 2 20200521
B 6 3 20200522
A 2 5 20200528
A 2 2 20200529
我的代码如下:
SELECT Client, Serial#, SUM(Hrs)
FROM MyTable
WHERE CONVERT(DATETIME, MyDate, 112) > DATEADD(day, -30, getdate())
GROUP BY Client, Serial#
这是我得到的错误 “将varchar数据类型转换为日期时间数据类型会导致超出范围的值。”
我尝试删除转换函数,并遇到另一个错误: “将varchar数据类型转换为日期时间数据类型会导致超出范围的值。”
所以现在我被困住了。预先感谢您的帮助
答案 0 :(得分:1)
您可以使用try_convert()
来解决此问题:
WHERE TRY_CONVERT(DATE, MyDate) > DATEADD(day, -30, getdate())
您的格式是SQL Server为日期常量定义的格式,因此您实际上不需要format参数。
您可以使用以下方法找到有问题的值:
select mydate
from t
where try_convert(date, mydate) is null and mydate is not null;
请注意,date
和datetime
的范围不同,因此仅使用date
可能会解决此问题。
答案 1 :(得分:0)
SELECT Client, Serial, SUM(Hrs)
FROM MyTable
WHERE CONVERT(DATETIME, MyDate) > DATEADD(day, -30, getdate())
GROUP BY Client, Serial
您不需要112格式进行比较
答案 2 :(得分:0)
您的转换功能看起来还不错(尽管112不需要去日期时间,也就是用于日期时间到字符串的转换。) 因此,我敢打赌,这些日期字符串中的某些地方会有一些不良数据。 日期必须在1753年1月1日至9999年12月31日之间。 尝试对该字段进行排序,看看列表的顶部或底部是否有可疑的东西。
您可以添加一个过滤器:
AND MyDate BETWEEN '17530101' and '99991231'
AND LEN(MyDate) = 8
答案 3 :(得分:0)
因为您别无选择,只能使用varchar作为日期,所以我会将一个GETDATE()值转换为varchar,而不是将所有行都转换为日期。可能是因为它们存储为YYYYMMDD。我认为这会提高性能(确定在此日期列上是否有索引)。
WHERE MyDate > CONVERT(varchar(10),dateadd(d,-30,getdate()),112)