Ask Learn
Preview
Please sign in to use this experience.
Sign inThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
神谷 雅紀
SQL Server Escalation Engineer
以下を実行した場合、最後の SELECT はどのような結果を返すでしょうか?
use tempdb
go
create table t (n int, d datetime)
go
insert into t values (0,'2013/5/1 23:59:59.990')
insert into t values (1,'2013/5/1 23:59:59.991')
insert into t values (2,'2013/5/1 23:59:59.992')
insert into t values (3,'2013/5/1 23:59:59.993')
insert into t values (4,'2013/5/1 23:59:59.994')
insert into t values (5,'2013/5/1 23:59:59.995')
insert into t values (6,'2013/5/1 23:59:59.996')
insert into t values (7,'2013/5/1 23:59:59.997')
insert into t values (8,'2013/5/1 23:59:59.998')
insert into t values (9,'2013/5/1 23:59:59.999')
insert into t values (10,'2013/5/2 00:00:00.000')
go
select * from t where d = '2013/5/1 23:59:59.999'
go
正解は以下です。
n d
----------- -----------------------
9 2013-05-02 00:00:00.000
10 2013-05-02 00:00:00.000
結果はクエリの検索条件 '2013/5/1 23:59:59.999' に一致しませんし、2 行返されています。なぜでしょう?
これは、datetime データ型の時刻範囲が 00:00:00 ~ 23:59:59.997 であり、ミリ秒の精度が .000、.003、.007 であるためです。
.000、.003、.007 以外の値は .000、.003、.007 に丸められます。
上の例のテーブルに格納されているデータを見てみると、以下のようになっています。
n d
----------- -----------------------
0 2013-05-01 23:59:59.990
1 2013-05-01 23:59:59.990
2 2013-05-01 23:59:59.993
3 2013-05-01 23:59:59.993
4 2013-05-01 23:59:59.993
5 2013-05-01 23:59:59.997
6 2013-05-01 23:59:59.997
7 2013-05-01 23:59:59.997
8 2013-05-01 23:59:59.997
9 2013-05-02 00:00:00.000
10 2013-05-02 00:00:00.000
例えば、2013/5/1 のデータを取り出そうとして、クエリの条件を WHERE d >= '2013-05-01 00:00:00.000' and d <= '2013-05-01 23:59:59.999' と書くと、それは、WHERE d >= '2013-05-01 00:00:00.000' and d <= '2013-05-02 00:00:00.000' と書いたことと同じになり、結果には 2013/5/2 のデータも含まれることになります。
datetime ではなく datetime2 または datetimeoffset であれば、1 ミリ秒もしくはそれ以上の精度を保てます。
create table t2 (n int, d datetime2)
go
insert into t2 values (9,'2013/5/1 23:59:59.999')
go
select * from t2
go
n d
----------- -----------------------
9 2013-05-01 23:59:59.9990000
datetime (Transact-SQL)
https://msdn.microsoft.com/ja-jp/library/ms187819.aspx
datetime2 (Transact-SQL)
https://msdn.microsoft.com/ja-jp/library/bb677335.aspx
datetimeoffset (Transact-SQL)
Please sign in to use this experience.
Sign in