【问题标题】:SQL- Difference between TIMESTAMP, DATE AND TIMESTAMP WITH TIMEZONE?SQL-TIMESTAMP、DATE 和 TIMESTAMP WITH TIMEZONE 之间的区别?
【发布时间】:2016-04-21 06:20:48
【问题描述】:

TIMESTAMPDATETIMESTAMP with TIMEZONE 有什么区别?

例如,如果我想搜索 01-JAN-199001-JAN-2000 之间的所有条目,我将如何在每种格式中这样做?

我一直在寻找时间戳为:

SELECT COUNT(*) FROM TABLE_NAME WHERE DATE BETWEEN '01-JAN-1990' AND '01-JAN-2000;

但我不确定使用什么格式来搜索DATETIMESTAMP WITH TIMEZONE

【问题讨论】:

  • 日期是yyyy-mm-dd,时间戳是yyyy-mm-dd hh:mm:ss - 有/没有关联的时区。这是 mysql 接受的唯一日期字符串格式类型,您的 dd-mmm-yyyy 不是有效的 mysql 日期字符串格式,将被视为无效/未知。试试between '1990-01-01' and '2000-01-01'
  • 你使用的是 MySQL?
  • 没有抱歉添加了我的错误标签。我正在使用 Oracle SQL 开发人员
  • @MarcB 不能自定义这个,即:stackoverflow.com/questions/8134493/…。在我的 sqldeveloper 中,我将日期格式设置为 DD-MON-RR?
  • 不知道。你有这个标签 mysql,所以我回答了 mysql。

标签: sql oracle date timestamp


【解决方案1】:

数据类型和它们之间的区别是in the documentation。简短的版本是:

  • DATE 精确到秒,不支持时区;
  • TIMESTAMP 的精度低至几分之一秒(最多九位小数,但您的操作系统也会影响这一点),但仍不支持时区;
  • TIMESTAMP WITH TIME ZONE 与 TIMESTAMP 具有相同的精度,但也支持时区,顾名思义;
  • TIMESTAMP WITH LOCAL TIME ZONE 在创建/查询会话的本地时区之间调整存储的值。

你可能会觉得this article 也很有趣。

当您比较存储在数据库中的日期时间值时,您应该使用相同数据类型的值进行比较。您不希望必须转换列中的每个值以进行比较,尤其是在列被索引的情况下。如果您有 DATE 列,则与 DATE 进行比较 - 不要作为字符串比较,也不要依赖字符串的隐式 conversion。当你这样做时:

WHERE date_col BETWEEN '01-JAN-1990' AND '01-JAN-2000'

您依赖于您的 NLS_DATE_FORMAT 是 DD-MON-YYYY 并且您的 NLS_DATE_LANGUAGE 是英语。如果其他人在另一个会话中运行相同的查询,他们的设置可能会导致查询失败(或者在某些情况下,给出错误的结果,这可能会更糟)。为了避免语言问题,最好使用月份数字而不是名称。如果您有要比较的字符串变量,您应该使用TO_DATE() 使用固定的已知格式掩码将字符串转换为 DATE - 不要依赖 NLS。如果你有一个固定值,你可以这样做,或者你可以使用date literal,它更短且明确。

使用您使用的格式,您还包括将列设置为 2000 年 1 月 1 日午夜的任何行,但不包括当天晚些时候的任何行。这可能是您想要的,但请确保您了解BETWEEN 的工作原理。如果您实际上要查找该十年内的日期,包括 1999 年 12 月 31 日的任何时间,您可以使用:

WHERE date_col >= DATE '1990-01-01' AND date_col < DATE '2000-01-01'

对于时间戳,您可以使用 TO_TIMESTAMP() 或时间戳文字:

WHERE ts_col >= TIMESTAMP '1990-01-01 00:00:00'
AND ts_col < TIMESTAMP '2000-01-01 00:00:00'

对于带有时区的时间戳,您可以使用 TO_TIMESTAMP_TZ() 或带有名称时区区域的时间戳文字:

WHERE tstz_col >= TIMESTAMP '1990-01-01 00:00:00 America/New_York'
AND tstz_col < TIMESTAMP '2000-01-01 00:00:00 America/New_York'

【讨论】:

    【解决方案2】:

    不要将日期与字符串进行比较。如果您的会话的 nls_date_format 恰好与您正在使用的字符串的格式匹配,它就可以工作。但是,对于具有不同配置的人,您的查询将立即失败。将日期与日期、时间戳与时间戳等进行比较。

    对于日期,您可以使用 ANSI 日期文字

    SELECT COUNT(*)
      FROM your_table
     WHERE date_column BETWEEN date '1900-01-01' AND date '2000-01-01'
    

    或者您可以使用带有显式格式掩码的to_date

    SELECT COUNT(*)
      FROM your_table
     WHERE date_column BETWEEN to_date('1900-01-01', 'YYYY-MM-DD') 
                           AND to_date('2000-01-01', 'YYYY-MM-DD')
    

    请注意,Oracle 中的date 始终包含日期和时间部分。如果您未在 to_date 中指定时间,则默认为午夜。如果您使用显式 to_date,则可以使用任何格式的字符串,只要它与您作为第二个参数传入的格式掩码匹配即可。

    对于时间戳,您可以使用 ANSI 时间戳文字

    SELECT COUNT(*)
      FROM your_table
     WHERE timestamp_column BETWEEN timestamp '1900-01-01 00:00:00.000' 
                                AND timestamp '2000-01-01 00:00:00.000'
    

    或者您可以使用带有显式格式掩码的to_timestamp

    SELECT COUNT(*)
      FROM your_table
     WHERE timestamp_column BETWEEN to_timestamp('1900-01-01 00:00:00.000', 'YYYY-MM-DD HH24:MI:SS.FFF') 
                                AND to_timestamp('2000-01-01 00:00:00.000', 'YYYY-MM-DD HH24:MI:SS.FFF') 
    

    如果您使用显式to_timestamp,则可以使用任何格式的字符串,只要它与您作为第二个参数传入的格式掩码匹配即可。

    对于带有时区的时间戳,您可能已经猜到了,您可以使用 ANSI 时间戳文字

    SELECT COUNT(*)
      FROM your_table
     WHERE timestamp_column BETWEEN timestamp '1900-01-01 00:00:00.000 -05:00' 
                                AND timestamp '2000-01-01 00:00:00.000 -05:00'
    

    或者您可以使用带有显式格式掩码的 to_timestamp_tz 函数

    SELECT COUNT(*)
      FROM your_table
     WHERE timestamp_column BETWEEN to_timestamp('1900-01-01 00:00:00.000 -05:00', 'YYYY-MM-DD HH24:MI:SS.FFF TZH:TZM') 
                                AND to_timestamp('2000-01-01 00:00:00.000 -05:00', 'YYYY-MM-DD HH24:MI:SS.FFF TZH:TZM') 
    

    如果您使用显式to_timestamp_tz,则可以使用任何格式的字符串,只要它与您作为第二个参数传入的格式掩码匹配即可。

    【讨论】:

      猜你喜欢
      • 2023-01-10
      • 2019-01-28
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 2010-10-09
      相关资源
      最近更新 更多