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
中存储日期,查询应该有效。如果您尝试以下脚本,您将获得预期的结果,AAA
、BBB
:
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'
不过,您仍然需要清理脏的出生日期,以删除任何不需要的时间部分。
我正在使用 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
中存储日期,查询应该有效。如果您尝试以下脚本,您将获得预期的结果,AAA
、BBB
:
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'
不过,您仍然需要清理脏的出生日期,以删除任何不需要的时间部分。