【问题标题】:combine date and time and get newest datetime结合日期和时间并获取最新的日期时间
【发布时间】:2016-10-02 02:02:04
【问题描述】:

我有一个给定的 oracle 表:

Datum 列是 DATEZeitVARCHAR2

我必须将它们组合到一个日期并获取它们的最大(=最新)日期。我用 c# 中的 oracle 阅读器阅读它并将它们组合起来,但为此我必须加载所有行,然后搜索最大值:

DateTime Tempdate = new DateTime(); Tempdate = Convert.ToDateTime(reader.GetValue(0).ToString()); Tempdate = Tempdate.AddHours(Convert.ToDateTime(reader.GetValue(1).ToString()).Hour); Tempdate = Tempdate.AddMinutes(Convert.ToDateTime(reader.GetValue(1).ToString()).Minute); Tempdate = Tempdate.AddSeconds(Convert.ToDateTime(reader.GetValue(1).ToString()).Second);

如何在 sql 语句中做到这一点,以便我只获得最新日期的行?

【问题讨论】:

  • 为什么将时间存储在单独的列中?
  • 这是一个给定的表..

标签: sql oracle date datetime


【解决方案1】:

您可以使用the to_dsinterval() function 将您的时间字符串添加到日期,在它前面加上一个零作为天数(因此它是一个有效的sql_format):

select datum, zeit, datum + to_dsinterval('0 ' || zeit)
from your_table:

DATUM               ZEIT     DATUM+TO_DSINTERVAL('0'||ZEIT)
------------------- -------- ------------------------------
2016-01-13 00:00:00 13:22:30 2016-01-13 13:22:30           
2016-01-13 00:00:00 13:26:30 2016-01-13 13:26:30           
2016-01-13 00:00:00 13:27:30 2016-01-13 13:27:30           
2016-01-13 00:00:00 13:28:30 2016-01-13 13:28:30           
2016-01-13 00:00:00 13:29:30 2016-01-13 13:29:30           
2016-01-13 00:00:00 13:30:30 2016-01-13 13:30:30           
2016-01-13 00:00:00 13:31:30 2016-01-13 13:31:30    

然后您只需在该计算值上使用max()

select max(datum + to_dsinterval('0 ' || zeit))
from your_table;

MAX(DATUM+TO_DSINTERVAL('0'||ZEIT))
-----------------------------------
2016-01-13 13:31:30                

要获得匹配的行,您可以这样做:

select datum, zeit --, other columns
from your_table
where datum + to_dsinterval('0 ' || zeit) = (
  select max(datum + to_dsinterval('0 ' || zeit))
  from your_table
);

虽然这必须打两次,但你可以通过 CTE 避免。

您还可以使用分析排名函数,按日期和时间排序:

select datum, zeit,  -- other columns,
  dense_rank() over (order by datum desc, zeit desc) as rnk
from your_table;

DATUM               ZEIT            RNK
------------------- -------- ----------
2016-01-13 00:00:00 13:31:30          1
2016-01-13 00:00:00 13:30:30          2
2016-01-13 00:00:00 13:29:30          3
2016-01-13 00:00:00 13:28:30          4
2016-01-13 00:00:00 13:27:30          5
2016-01-13 00:00:00 13:26:30          6
2016-01-13 00:00:00 13:22:30          7

然后选择排名第一的行:

select datum, zeit --, other columns
from (
  select t.*, dense_rank() over (order by datum desc, zeit desc) as rnk
  from your_table t
)
where rnk = 1;

DATUM               ZEIT   
------------------- --------
2016-01-13 00:00:00 13:31:30

如果您从问题建议的行中获取其他数据,那么如果您可能有两行具有相同的日期和时间,您将需要决定如何打破平局并选择其中之一。

【讨论】:

    【解决方案2】:

    您可以在时间组件上使用TO_DATE()

    SELECT datum + ( TO_DATE( zeit, 'HH24:MI:SS' ) - TRUNC( TO_DATE( zeit, 'HH24:MI:SS' ) ) )
    FROM   table_name
    

    然后,要获得最大值,您可以在此计算值上使用 MAX(),或者假设可以使用日期/字母数字顺序比较这些值(假设时间分量不超过 23:59:59),您可以首先找到最大值:

    SELECT datum,
           zeit
    FROM   (
      SELECT datum,
             zeit,
             ROW_NUMBER() OVER ( ORDER BY datum DESC, zeit DESC ) AS rn
      FROM   table_name
    )
    WHERE  rn = 1
    

    这可以使用您在表上的任何索引。

    然后在这一行上使用我的第一个查询(或@AlexPoole 的TO_DSINTERVAL() 解决方案)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 2022-12-10
      • 2013-11-29
      • 1970-01-01
      相关资源
      最近更新 更多