【问题标题】:Migrating Oracle query to PostgreSQL将 Oracle 查询迁移到 PostgreSQL
【发布时间】:2019-10-16 07:08:11
【问题描述】:

你能帮我解决这个问题吗?如何将以下查询转换为 PostgreSQL。

以下查询在 PostgreSQL 中执行时与在 Oracle 中执行时给出不同的输出。

SELECT 
  to_char(to_date('01011970','ddmmyyyy') + 1/24/60/60 * 4304052,'dd-mon-yyyy hh24:mi:ss') 
from dual;

【问题讨论】:

  • 尽量不要用不相关的东西来标记。 C++ 在这里不是一个因素。
  • 即使在 Oracle 中,这也是一个糟糕的查询 - 将 数字 添加到日期,然后尝试将其转换为本地化字符串。该数字是根据多个 integer 除法计算得出的,结果是 0,然后是整数乘法,结果也是 0
  • 这个查询首先尝试做什么?将 Unix 时间戳转换为实际日期?如果是这样,为什么要在最后产生一个字符串
  • 我已经尝试删除双重但得到不同的价值。
  • o/p postgresql : to_char ---------- 01-jan-1970 00:00:00

标签: sql postgresql


【解决方案1】:

假设您想使用与 Oracle 中相同的表达式来计算结果值。

当您简单地删除 from dual 时它不起作用的原因是因为该表达式被评估为 0,因为整数除法会将结果截断为 0。

select 1/24/60/60 * 4304052;
 ?column?
----------
        0
(1 row)

如果我将其中一个设为小数,它将为您提供所需的结果

select 1.0/24/60/60 * 4304052;
          ?column?
-----------------------------
 49.815416666666666347848000

现在,更改此设置后,您的表达式将返回您在 Oracle 中获得的相同结果。

SELECT  to_char( to_date('01011970','ddmmyyyy')
 +  INTERVAL '1 DAY' *  (1.0/24/60/60 * 4304052) ,'dd-mon-yyyy hh24:mi:ss') ;
       to_char
----------------------
 19-feb-1970 19:34:12
(1 row)

请注意,我必须添加一个区间表达式,因为与 Oracle 不同,Postgres DATE 不存储时间组件,简单地添加一个数字到日期会导致错误。使用间隔将确保将其评估为时间戳。

knayak=# select pg_typeof( current_date);
 pg_typeof
-----------
 date
(1 row)

knayak=# select pg_typeof( current_date + INTERVAl '1 DAY');
          pg_typeof
-----------------------------
 timestamp without time zone
(1 row)

【讨论】:

    【解决方案2】:

    我想你想要:

    select '1970-01-01'::date + 4304052 * interval '1 second';
    

    如果你真的想要,你可以使用to_char() 将它转换回字符串:

    select to_char('1970-01-01'::date + 4304052 * interval '1 second', 'YYYY-MM-SS HH24:MI:SS');
    

    【讨论】:

      猜你喜欢
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      • 2016-08-22
      • 2020-02-15
      • 2014-01-26
      • 2012-04-05
      • 1970-01-01
      • 2020-10-24
      相关资源
      最近更新 更多