【问题标题】:SQL Query to convert number value into dateSQL查询将数值转换为日期
【发布时间】:2019-09-19 18:26:31
【问题描述】:

在我的交易表中有 id Number(11),name Varchar2(25),transactiondate number(22)。

需要编写 SQL 查询来获取交易详情。 transactiondate 应该以日期和时间格式返回,而不是数字。

transaction table 
ID   Name   transactiondate    
1    AAA    2458010   
2    BBB    2458351
3    CCC    2458712

当我执行以下查询时,我得到了以下结果

Select * from transaction where transactiondate <= TOCHAR(todate('2019/09/17 00:00:00', 'YYYY/MM/DD hh24:mi:ss') , 'J');
ID   Name   transactiondate    
1    AAA    2458010   
2    BBB    2458351

当我尝试执行以下查询时出现查询语法错误

Select name, convert(datetime, convert(varchar(10), transactiondate)) as txndateformat 
from transaction;

期望查询必须以日期格式而不是数字形式返回名称和交易日期。

当我执行以下查询时,我得到了以下结果

Desc transaction;
Name             Null?     Type
Id               Not Null  Number(19)
Name             Not Null  VarChar2(100)
transactiondate  Not Null  Number(22)

【问题讨论】:

  • 你觉得2456702代表的是哪个日期?
  • Oracle没有datetime,你确定你用的是Oracle吗?
  • 到底为什么要将时间戳值存储在number 列中?这真是个坏主意。如果要存储日期和时间值,请使用定义为 timestamp 的列。
  • Oracle 具有“儒略日期”格式 - 将日期存储为数字。它不包括时间戳。 SELECT TO_DATE(2456702,'J') FROM dual; 2014 年 2 月 13 日返回

标签: sql oracle


【解决方案1】:

这完全取决于您何时测量零时间以及您的单位是什么。

以下是一些典型的解决方案:

Oracle 设置

CREATE TABLE transaction ( ID, Name, transactiondate ) AS
SELECT 1, 'AAA', 2456702 FROM DUAL UNION ALL
SELECT 2, 'BBB', 2456703 FROM DUAL

查询

SELECT name,
       TO_DATE( transactiondate, 'J' )
         AS julian_date,
       DATE '1970-01-01' + NUMTODSINTERVAL( transactiondate / 1000, 'SECOND' )
         AS unix_timestamp,
       DATE '1970-01-01' + NUMTODSINTERVAL( transactiondate, 'SECOND' )
         AS seconds_since_1970,
       DATE '1970-01-01' + NUMTODSINTERVAL( transactiondate, 'MINUTE' )
         AS minutes_since_1970,
       DATE '1970-01-01' + NUMTODSINTERVAL( transactiondate, 'HOUR' )
         AS hours_since_1970,
       DATE '1900-01-01' + NUMTODSINTERVAL( transactiondate, 'HOUR' )
         AS hours_since_1900,
       DATE '1899-12-30' + transactiondate
         AS excel_date
FROM   transaction

输出

姓名 |朱利安_日期 | UNIX_TIMESTAMP | SECONDS_SINCE_1970 | MINUTES_SINCE_1970 | HOURS_SINCE_1970 | HOURS_SINCE_1900 | EXCEL_DATE :--- | :----------------- | :----------------- | :----------------- | :----------------- | :----------------- | :----------------- | :----------------- AAA | 2014-02-13 00:00:00 | 1970-01-01 00:40:56 | 1970-01-29 10:25:02 | 1974-09-03 01:02:00 | 2250-04-05 14:00:00 | 2180-04-04 14:00:00 | 8626-03-21 00:00:00 血脑屏障 | 2014-02-14 00:00:00 | 1970-01-01 00:40:56 | 1970-01-29 10:25:03 | 1974-09-03 01:03:00 | 2250-04-05 15:00:00 | 2180-04-04 15:00:00 | 8626-03-22 00:00:00

db小提琴here

(注意:如果你想支持1900-03-01 之前的值,Excel dates 会稍微复杂一些,但大多数人不需要这个,所以上面只包含简化版本。) p>

【讨论】:

  • 。 .好答案。给定值和数据库,OP 可能打算使用 Julian 日期格式。
  • 感谢您的宝贵支持。它对我有用 Select name, TO_DATE(transactiondate, 'J') as txn_date from transaction;
【解决方案2】:

我假设数字是纪元数

对于 SQL Server:

SELECT DATEADD(ss, 2456702, '19700101') --ss means interval = seconds

对于甲骨文:

select to_date('19700101', 'YYYYMMDD') + ( 1 / 24 / 60 / 60) * 2456702
from dual;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    • 2021-10-03
    相关资源
    最近更新 更多