首页 > 解决方案 > 修改查询以使其工作而不需要设置 NLS_DATE_FORMAT

问题描述

我以下查询:

SELECT
    trunc(estimatedenddate,'hh') AS reg_date,
    COUNT(*)
FROM
    (
        SELECT
            attr_value,
            TO_DATE( (DATE '1970-01-01' + (1 / 24 / 60 / 60 / 1000) * attr_value),'yyyy-mm-dd HH24:mi:ss') AS estimatedenddate
        FROM
            attr
        WHERE
            attr_name = 'createTimestamp'
    )
WHERE
    estimatedenddate > TO_DATE('01/JUN/2018','dd/mon/yyyy')
GROUP BY
    trunc(estimatedenddate,'hh')
ORDER BY
    reg_date DESC;

当我设置NLS_DATE_FORMAT时它可以工作。请参阅dbfiddle

但是,如果我不设置NLS_DATE_FORMAT,则查询不会产生任何结果。见dbfiddle

如何修改此查询以使其在不设置NLS_DATE_FORMAT的情况下工作?

标签: sqloracleoracle11gsql-date-functionssqldatetime

解决方案


TO_DATE( date_string, format_model )第一个参数为字符串,但您传递的DATE数据类型 Oracle 将尝试提供帮助并使用其默认格式模型隐式转换为预期的字符串数据类型;所以你的内部查询是有效的:

SELECT attr_value,
       TO_DATE(
         TO_CHAR(
           DATE '1970-01-01' + (1 / 24 / 60 / 60 / 1000) * attr_value,
           (SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
         ),
         'yyyy-mm-dd HH24:mi:ss'
       ) AS estimatedenddate
FROM   attr
WHERE  attr_name = 'createTimestamp'

相反,您可以删除该TO_DATE()功能:

SELECT trunc(estimatedenddate,'hh') AS reg_date,
       COUNT(*)
FROM   (
  SELECT DATE '1970-01-01' + (1 / 24 / 60 / 60 / 1000) * attr_value AS estimatedenddate
  FROM   attr
  WHERE  attr_name = 'createTimestamp'
)
WHERE    estimatedenddate > DATE '2018-06-01'
GROUP BY trunc(estimatedenddate,'hh')
ORDER BY reg_date DESC;

推荐阅读