为什么比较Firebird中的Timestamp和date导致奇怪的值?

时间:2016-03-11 18:48:14

标签: sql firebird

我正在比较一些日期和时间,发现我不理解Firebird Date Literalstheir 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'是假的,但是当我对cast执行TIMESTAMP时,这是真的吗?

为什么'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'为假?

请注意最后两个表达式中日期和时间之间的额外空间。我确实认为额外的空间不会改变结果,你可以从first link中看到这句话:

  

日期文字中的空格

     

元素之间可以出现空格或制表符。日期部分必须与时间部分分开至少一个空格。

1 个答案:

答案 0 :(得分:4)

问题是您没有在大多数表达式中比较时间戳和日期。相反,您正在比较字符串CHAR)文字。

回答您的具体问题:

  1. '2016-01-25 00:00:00.000' <= '2016-01-25'为false,因为字符串排序2016-01-25出现在2016-01-25 00:00:00.000之前
  2. '2016-01-25 00:00:00.000' <= '2016-01-25 23:59:59.999'为false,因为2016-01-25 23:59:59.999在时间部分之前有第二个空格,而在字符串排序中,空格位于0之前。
  3. 要使用日期或时间戳文字,您需要使用DATETIMESTAMP显式地为字符串文字添加前缀,或者您需要使用强制转换,否则它只是一个字符串。将您的查询更改为下面的查询,您就可以获得预期的值:

    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