我尝试使用T-SQL查询来获取过去一周的数据。我有视图返回以下列:
Name (varchar)
Date Registered (DateTime)
我正在尝试使用该视图仅获取最后几周的数据。但是,我一直收到错误:
从字符串转换日期和/或时间时转换失败。
这是我的sql:
DECLARE @Now DATETIME = GETDATE();
DECLARE @6DaysAgo DATETIME = DATEADD(day,-6,@Now);
SELECT *
FROM vw_Logs l
WHERE convert(DATETIME, 'l.Date Registered', 121) BETWEEN @6DaysAgo and @Now
当我编写完全相同的SQL语句时,使用表而不是视图,我不会收到错误。
DECLARE @Now DATETIME = GETDATE();
DECLARE @6DaysAgo DATETIME = DATEADD(day,-6,@Now);
SELECT *
FROM tbl_Logs l
WHERE convert(DATETIME, l.DateRegistered, 121) BETWEEN @6DaysAgo and @Now
我怀疑它与列名有关?视图有一个空格(Date Registered
),而表格没有(DateRegistered
)。
是这样的吗?如果是这样,如何从视图中获取最后几周的数据,而无需更改列名?
答案 0 :(得分:3)
不完全相同的SQL语句!您需要在视图中用方括号括起您的列名称及其中的空格 - 而不是单引号:
SELECT *
FROM vw_Logs l
WHERE CONVERT(DATETIME, l.[Date Registered], 121) BETWEEN @6DaysAgo AND @Now
将该表达式放在单引号中会使其成为字符串文字,并且字符串文字实际上不能很好地转换为DATETIME
....
答案 1 :(得分:1)
我在这里看到了几个问题。首先,为什么要将DateRegistered转换为日期时间?你声明它已经是一个日期时间列吗?进行比较时格式化它不会有任何区别。但它确实会使您的查询变为nonSARGable,并且现在忽略了该列的任何索引。
我看到的第二个问题是我猜你在过去6天内想要什么。你编码的方式不准确。您的计算将排除在当前时间之前的那一天发生的任何行。
查看变量的值。
DECLARE @Now DATETIME = GETDATE();
DECLARE @6DaysAgo DATETIME = DATEADD(day,-6,@Now);
select @Now, @6DaysAgo
相反,你可以做这样的事情。它是SARGable,它没有时间戳的问题。
SELECT [Column List]
FROM vw_Logs l
WHERE l.[Date Registered] > dateadd(day, datediff(day, 0, getdate()) - 6, 0)
and l.[Date Registered] < GETDATE()