【问题标题】:Need to get in DATE Format (YYYY-MM-DD) from a NUMBER Data type column (123456789)需要从 NUMBER 数据类型列 (123456789) 获取 DATE 格式 (YYYY-MM-DD)
【发布时间】:2020-01-22 06:28:52
【问题描述】:

我有一个数据类型为NUMBER(32,0) 的列。此列实际上存储来自应用程序的日期和时间戳。

我需要将此number 数据类型列导出为date

即,

select column_name from table_name;

 o/p:
1368046452000

我尝试使用此选项导出为日期,

SELECT TO_DATE( 
         TO_TIMESTAMP('1970-01-01'
                     ,'YYYY-MM-DD'
         ) + NUMTODSINTERVAL(column_name/1000, 'SECOND')
        ,'YYYY-MM-DD')
FROM  table_name;

它给了我预期的输出"15-JUL-23"

问题:

这张表有大约 900 多列,其中 50 多列就像这个数字 data_type 一样,其中存储了日期和时间。我需要将这 50 多列转换/格式化为YYYY-MM-DD

如何从表中获取/导出/选择所有列值,其中上述数字 data_type 列应以YYYY-MM-DD 格式返回?

请帮忙!!

谢谢, 卡提克

【问题讨论】:

  • 900 多列。你是认真的?日期存储为数字,你是认真的吗?
  • 如果您要创建一个新表,您可以从当前表的选择中创建具有适当类型的表。或者您可以创建具有适当类型的视图/物化视图。您是否正在更改应用程序以在将来插入正确的日期类型?
  • @AnkitBajpai,是的。该表有 900 多列,50 多列是数字数据类型,它以数字形式存储日期和时间。只需将这些数字数据类型值导出为日期格式。你能帮忙吗?
  • @ZynonPutneyII。我们没有触及当前表,因为这些表直接由应用程序前端使用,我们现在和将来都不会更改当前表。我只需要使用 sql devoper 将存储在数字数据类型中的日期和时间值导出为 DATE 格式。请推荐!
  • 不要在已经是 DATE(或 TIMESTAMP)数据类型的东西上使用 TO_DATE,因为 TO_DATE 需要一个字符串作为其第一个参数,然后当默认日期到字符串格式与您的显式 YYYY-MM-DD 格式不匹配(db<>fiddle 及其默认值会为您的查询提供 ORA-01858 异常)。如果要将TIMESTAMP 转换为DATE,请使用CAST( value AS DATE )

标签: sql oracle


【解决方案1】:

您的时间显示为 Unix 时间戳,该时间戳将在 UTC 时区中以自 1970 年 1 月 1 日以来的毫秒数为单位。

你可以使用:

SELECT TIMESTAMP '1970-01-01 00:00:00 UTC' + column_name * INTERVAL '0.001' SECOND
FROM   table_name;

这将获得 TIMESTAMP 数据类型的值(因为它可以有小数秒)。

如果您想将其作为DATE,则使用CAST 进行转换:

SELECT CAST(
         TIMESTAMP '1970-01-01 00:00:00 UTC' + column_name * INTERVAL '0.001' SECOND
         AS DATE
       )
FROM   table_name;

如果您希望它在特定时区(而不是 UTC),请使用AT TIME ZONE 'your_tz'

SELECT CAST(
         ( TIMESTAMP '1970-01-01 00:00:00 UTC' + column_name * INTERVAL '0.001' SECOND )
           AT TIME ZONE 'PST'
           AS DATE
       )
FROM   table_name;

所以对于你的测试数据:

CREATE TABLE table_name ( column_name ) AS
SELECT 1368046452000 FROM DUAL;

查询:

SELECT ( TIMESTAMP '1970-01-01 00:00:00 UTC' + column_name * INTERVAL '0.001' SECOND )
         AS UTC_TIMESTAMP,
       CAST(
         ( TIMESTAMP '1970-01-01 00:00:00 UTC' + column_name * INTERVAL '0.001' SECOND )
           AS DATE
       ) AS UTC_DATE,
       CAST(
         ( TIMESTAMP '1970-01-01 00:00:00 UTC' + column_name * INTERVAL '0.001' SECOND )
           AT TIME ZONE 'PST'
           AS DATE
       ) AS PST_DATE
FROM   table_name;

会输出:

UTC_TIMESTAMP | UTC_DATE | PST_DATE :-------------------------------- | :----------------- | :----------------- 2013-05-08 20:54:12.000000000 UTC | 2013-05-08 20:54:12 | 2013-05-08 13:54:12

db小提琴here

【讨论】:

  • 您能否告诉我如何获取此表中所有 900 多列的列表,包括应用于其中所有数字数据类型列的日期格式(如您上面建议的)?
【解决方案2】:

只是为了减少编码,创建一个函数

Create or replace function MyConvert(p_val in number ) return varchar2
as
begin
    return TO_CHAR(TO_DATE('1970/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS') + 
                NUMTODSINTERVAL(p_val / 1000,'SECOND'), 'YYYY-MM-DD');
end;

然后在你的代码中做

SELECT MyConvert(col1) col1, ..... MyConvert(col50) col50 FROM table

您得到的“日期格式”实际上不是日期 - 这是日期的字符串表示形式

【讨论】:

  • Unix 时间戳基于 UTC 时间,因此结果也是 UTC 时间。这可能没问题 - 这取决于应用程序要求(尤其是当值关闭到午夜时)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-02
相关资源
最近更新 更多