SQL 服务器:日期相同的地方

SQL Server : where with same date

我正在使用 SQL 服务器。我有两个使用这些字段的日期过滤器,如下面的查询所示。

SELECT * 
FROM student
WHERE 
    Dateofbirth >= '2014-10-03'
    AND Dateofbirth <= '2014-10-03'

使用同一日期时未列出任何结果。如果我将日期更改为

SELECT * 
FROM student
WHERE 
    Dateofbirth >= '2014-10-03'
    AND Dateofbirth <= '2014-10-04'

我列出了我的记录。

同样的查询在 MySql 中运行良好。有人能帮我吗?为什么这在 SQL 服务器中不起作用?

SELECT * FROM student
WHERE Dateofbirth >= '2014-10-03'
AND Dateofbirth <= '2014-10-03'

这意味着只显示只有 2014-10-03 值的数据。你的日期中也有小时,你的日期字符串没有小时、分钟、秒。所以在比较中它不会得到。

当你使用日期比较时,这个问题将通过类型转换或正确的格式解决。

SELECT * FROM student
WHERE cast ( Dateofbirth as date) >= cast ( '2014-10-03' as date)
AND cast( Dateofbirth as date) <= cast( '2014-10-03' as date)

这将在日期部分而不是时间中设置两个值。

当您使用 2014-10-04 时表示包括所有时间并得到结果。

您也可以在运算符之间使用,包括开始日期和结束日期。

SELECT * FROM student
WHERE cast ( Dateofbirth as date) between cast ( '2014-10-03' as date) and cast ( '2014-10-04' as date)

or 
SELECT * FROM student
WHERE Dateofbirth  between '2014-10-03' and '2014-10-04' 

查看问题 Dateofbirth 可能是日期时间列。

日期时间列同时包含日期部分和时间 part.So,仅包含日期的查询将转换为

SELECT * FROM student
WHERE Dateofbirth >= '2014-10-03 00:00:00.000'
AND Dateofbirth <= '2014-10-03 00:00:00.000'

所以,要获得一整天的查询应该像

SELECT * FROM student
WHERE Dateofbirth >= '2014-10-03 00:00:00.000'
AND Dateofbirth <= '2014-10-03 23:59:59.997

如前所述,您的专栏的时间部分(hour/minute 等)是该行为的原因。

在 T-SQL 中,您还可以使用 DATEDIFF 获取特定日期的数据:

SELECT * FROM student
WHERE DATEDIFF(d, Dateofbirth, '2014-10-03') = 0

如果您只在 Dateofbirth 中存储日期,查询应该有效。如果您尝试以下脚本,您将获得预期的结果,AAABBB:

create table students(
    ID int primary key identity,
    Name varchar(50),
    Dateofbirth datetime)


insert into students (Name,Dateofbirth)
values ('AAA','2014-10-03'),
    ('BBB','2014-10-03'),
    ('CCC','2014-10-04')



select * 
from students 
where Dateofbirth between '2014-10-03' and '2014-10-03'

select * 
from students 
where Dateofbirth>='2014-10-03' and Dateofbirth<='2014-10-03'

我怀疑您使用 datetime 列存储出生日期。 datetime 包括时间,这意味着 2014-10-03 实际上是 2014-10-03 00:00:00。我怀疑错误或 ETL 怪癖添加了一个时间组件,可能是以时区偏移的形式?

您应该将列的类型更改为 date,它只存储日期。这具有商业意义,因为我怀疑您是否想存储学生的实际出生时间,并防止意外输入时间。

如果您不想更改列的类型,您可以在比较前将该字段的值转换为 date。通常,对字段值应用任何类型的操作都意味着您不能使用任何基础索引。在这种情况下 SQL 服务器足够智能,可以检测强制转换并使用 Dateofbirth 列上的任何基础索引:

select *
from students 
where cast(BirthDate as date)>='2014-10-04' and cast(BirthDate as date)<='2014-10-04'

不过,您仍然需要清理脏的出生日期,以删除任何不需要的时间部分。