查询日期范围

Mar*_*din 0 sql-server sql-server-2000 date time

我查询此 SQL 查询:

SELECT * FROM [DB].[dbo].[Table]
WHERE [DATE] BETWEEN '01-01-2016' AND '31-03-2016'
AND ([TIME] >= '00:00:00' OR [DATE] > '01-01-2016')
AND ([TIME] <= '00:00:00' OR [DATE] < '31-03-2016');
Run Code Online (Sandbox Code Playgroud)

但在 SQL Studio 中,结果为另一个日期和时间。

在此处输入图片说明

[DATE] = VARCHAR(10) (DD-MM-YYYY)
[TIME] = VARCHAR(10) (HH:MM:SS) 24h
Run Code Online (Sandbox Code Playgroud)

怎么修 ?

Aar*_*and 9

优先级 1:修复桌子。您不应该在varchar列中存储日期和时间数据,并且很可能不应该将日期和时间分成各自独立的列。您还应该避免将保留字/关键字作为列,但我怀疑您可能只是简化了实际的表结构。

优先级 2:停止使用 BETWEEN。这可能会导致各种问题,尤其是当您修复表格并将日期和时间合并到单个列中时。范围的结尾因数据类型而异,但使用 >= 范围的开始和 < NEXT 范围的开始将始终有效。考虑到表已更改,您可以说如下(我不确定您要对第二个和第三个 where 子句做什么,但您应该能够查看日期列):

WHERE [DATE] >= '20160101'
  AND [DATE] <  '20160401';
-- note that I don't have to look at the TIME column at all
-- also note that I use a *SAFE* format for the string literal
Run Code Online (Sandbox Code Playgroud)

优先级 3:停止将日期作为字符串进行比较。如果您无法修复该表,则您的子句需要首先将字符串列转换为有效的日期/时间值,因此您不会比较字符串。并且您需要使用在 SQL Server中安全的字符串格式;dd-mm-yyyy不是这些格式之一-它可以打破(或只返回了错误的数据。)如果更改语言设置,例如。

WHERE CONVERT(datetime, [DATE], 105) >= '20160101' 
  AND CONVERT(datetime, [DATE], 105) <  '20160401';
-- 103 makes sure the stored strings are interpreted as d/m/y
Run Code Online (Sandbox Code Playgroud)

补充阅读:

  • @Marvin 当您使用古老的、不受支持的 SQL Server 版本时,请始终正确标记问题。此外,您错过了我的部分建议:将它们合并到一个“日期时间”列中。为什么它们首先将列分开? (3认同)
  • @Marvin 您需要更好地定义“添加时间”的含义 - 另外,请不要使用 `&lt;= '20160331'`,使用 `&lt; '20160401'`。请。`&lt;=` 不好是有原因的。 (3认同)