为什么在 Firebird 中比较时间戳和日期会产生奇怪的值?
Why comparing Timestamp and date in Firebird result in weird value?
我正在比较一些日期和时间,发现我并不像我想的那样理解Firebird Date Literals and their conversions。
请看这个查询:
SELECT
iif('2016-01-25' <= '2016-01-25', 1, 0) AS TSCASE,
iif('2016-01-25 00:00:00.000' <= '2016-01-25', 1, 0) AS TSCASE1,
iif('2016-01-25 00:00:00.000' <= cast('2016-01-25' as timestamp), 1, 0) AS TSCASE2,
iif(cast('2016-01-25 00:00:00.000' as timestamp) <= '2016-01-25', 1, 0) AS TSCASE3,
iif('2016-01-25 00:00:00.000' <= '2016-01-25 00:00:00.000', 1, 0) AS TSCASE4,
iif('2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999', 1, 0) AS TSCASE5,
iif('2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999', 1, 0) AS TSCASE6,
iif('2016-01-25 00:00:00.000' <= cast('2016-01-25 23:59:59.999' as timestamp), 1, 0) AS TSCASE7
FROM RDB$DATABASE
我希望每一列的结果都是 1。但这是结果:
TSCASE TSCASE1 TSCASE2 TSCASE3 TSCASE4 TSCASE5 TSCASE6 TSCASE7
1 0 1 1 1 1 0 1
那么为什么 '2016-01-25 00:00:00.000' <= '2016-01-25'
是假的,但是,当我对 TIMESTAMP
执行任何 cast
时,是真的?
还有为什么'2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999'
和'2016-01-25 00:00:00.000' <= cast('2016-01-25 23:59:59.999' as timestamp)
是真的,而'2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999'
是假的?
请注意最后两个表达式中日期和时间之间的额外 space。我确实认为额外的 space 不会改变结果,正如您在 first link:
中看到的那样
White Space in Date Literals
Spaces or tabs can appear between elements. A date part must be separated from a time part by at least one space.
问题是您没有在大多数表达式中比较时间戳和日期。相反,您正在比较 string (CHAR
) 文字。
回答您的具体问题:
'2016-01-25 00:00:00.000' <= '2016-01-25'
是假的,因为在字符串排序中 2016-01-25
在 2016-01-25 00:00:00.000
之前
'2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999'
为假,因为 2016-01-25 23:59:59.999
在时间部分之前有第二个 space,而在字符串排序中 space 在 0
之前。
要使用日期或时间戳字面量,您要么需要在字符串字面量前显式添加 DATE
或 TIMESTAMP
前缀,要么需要使用强制转换,否则它只是一个字符串。将您的查询更改为以下查询,您确实得到了预期值:
SELECT
iif(DATE'2016-01-25' <= DATE'2016-01-25', 1, 0) AS TSCASE,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= DATE'2016-01-25', 1, 0) AS TSCASE1,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= cast('2016-01-25' as timestamp), 1, 0) AS TSCASE2,
iif(cast('2016-01-25 00:00:00.000' as timestamp) <= DATE'2016-01-25', 1, 0) AS TSCASE3,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= TIMESTAMP'2016-01-25 00:00:00.000', 1, 0) AS TSCASE4,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= TIMESTAMP'2016-01-25 23:59:59.999', 1, 0) AS TSCASE5,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= TIMESTAMP'2016-01-25 23:59:59.999', 1, 0) AS TSCASE6,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= cast('2016-01-25 23:59:59.999' as timestamp), 1, 0) AS TSCASE7
FROM RDB$DATABASE
我正在比较一些日期和时间,发现我并不像我想的那样理解Firebird Date Literals and their conversions。
请看这个查询:
SELECT
iif('2016-01-25' <= '2016-01-25', 1, 0) AS TSCASE,
iif('2016-01-25 00:00:00.000' <= '2016-01-25', 1, 0) AS TSCASE1,
iif('2016-01-25 00:00:00.000' <= cast('2016-01-25' as timestamp), 1, 0) AS TSCASE2,
iif(cast('2016-01-25 00:00:00.000' as timestamp) <= '2016-01-25', 1, 0) AS TSCASE3,
iif('2016-01-25 00:00:00.000' <= '2016-01-25 00:00:00.000', 1, 0) AS TSCASE4,
iif('2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999', 1, 0) AS TSCASE5,
iif('2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999', 1, 0) AS TSCASE6,
iif('2016-01-25 00:00:00.000' <= cast('2016-01-25 23:59:59.999' as timestamp), 1, 0) AS TSCASE7
FROM RDB$DATABASE
我希望每一列的结果都是 1。但这是结果:
TSCASE TSCASE1 TSCASE2 TSCASE3 TSCASE4 TSCASE5 TSCASE6 TSCASE7
1 0 1 1 1 1 0 1
那么为什么 '2016-01-25 00:00:00.000' <= '2016-01-25'
是假的,但是,当我对 TIMESTAMP
执行任何 cast
时,是真的?
还有为什么'2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999'
和'2016-01-25 00:00:00.000' <= cast('2016-01-25 23:59:59.999' as timestamp)
是真的,而'2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999'
是假的?
请注意最后两个表达式中日期和时间之间的额外 space。我确实认为额外的 space 不会改变结果,正如您在 first link:
中看到的那样White Space in Date Literals
Spaces or tabs can appear between elements. A date part must be separated from a time part by at least one space.
问题是您没有在大多数表达式中比较时间戳和日期。相反,您正在比较 string (CHAR
) 文字。
回答您的具体问题:
'2016-01-25 00:00:00.000' <= '2016-01-25'
是假的,因为在字符串排序中2016-01-25
在2016-01-25 00:00:00.000
之前
'2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999'
为假,因为2016-01-25 23:59:59.999
在时间部分之前有第二个 space,而在字符串排序中 space 在0
之前。
要使用日期或时间戳字面量,您要么需要在字符串字面量前显式添加 DATE
或 TIMESTAMP
前缀,要么需要使用强制转换,否则它只是一个字符串。将您的查询更改为以下查询,您确实得到了预期值:
SELECT
iif(DATE'2016-01-25' <= DATE'2016-01-25', 1, 0) AS TSCASE,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= DATE'2016-01-25', 1, 0) AS TSCASE1,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= cast('2016-01-25' as timestamp), 1, 0) AS TSCASE2,
iif(cast('2016-01-25 00:00:00.000' as timestamp) <= DATE'2016-01-25', 1, 0) AS TSCASE3,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= TIMESTAMP'2016-01-25 00:00:00.000', 1, 0) AS TSCASE4,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= TIMESTAMP'2016-01-25 23:59:59.999', 1, 0) AS TSCASE5,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= TIMESTAMP'2016-01-25 23:59:59.999', 1, 0) AS TSCASE6,
iif(TIMESTAMP'2016-01-25 00:00:00.000' <= cast('2016-01-25 23:59:59.999' as timestamp), 1, 0) AS TSCASE7
FROM RDB$DATABASE