【问题标题】:SQL: combine case and number to date conversionSQL:结合大小写和数字到日期的转换
【发布时间】:2015-03-03 08:47:17
【问题描述】:

我想做一个 sql 语句,在一个表中计算 2 个日期值的减法。如果值为负,我只想将其显示为 0 值。

数值是支付处于当前状态的秒数。 我用技巧将它转换为时间值(日期类型)。

我当前的代码是

SELECT 
max(CASE WHEN t1.time_event < SYSDATE and t2.time_event > SYSDATE THEN to_char(to_date(max(round(SYSDATE - t1.time_event) * 24 * 60 * 60)),'ssssss'),'hh24:mi:ss') else to_char(to_date(0)) END) as "current_age"
from tbl_dummyfeed t1 join tbl_dummyfeed t2 on t1.payment_Id = t2.payment_id
where t1.event = 'accepted' and t2.event = 'enriched');

【问题讨论】:

  • 添加了基于sysdateto_char() 用法的oracle 标签
  • MAX 是一个聚合函数,即只返回一行(只要没有 GROUP BY。)那么为什么是 DISTINCT?
  • 好的,我删除了 distinct,但我认为这不是商业案例。
  • 你的“丰富”时间真的在未来,而不仅仅是“接受”时间之后吗?您真的是要从当前的不中减去接受的时间,而不是匹配的丰富时间吗?这个计算什么时候可以是负数?
  • 是的,因为我想知道此时有多少付款处于特定状态。所以下一个状态永远是未来。

标签: sql oracle date case


【解决方案1】:

您可以使用类似的日期“技巧”,即将小数天数差异添加到时间部分为午夜的标称日期 - 您可以使用固定日期或 trunc(sysdate),只要时间以午夜结束 - 无需乘以 24*60*60。 (您的to_date() 解决方案隐含地做了同样的事情,有效地将秒数添加到当月第一天的午夜;但这可能更清楚一点)。但您也可以将case 子句移到where 过滤器中

select to_char(date '1970-01-01'
  + nvl(max(sysdate - t1.time_event), 0), 'HH24:MI:SS') as "current_age"
from tbl_dummyfeed t1
join tbl_dummyfeed t2
on t1.trax_id = t2.trax_id
where t1.event = 'accepted'
and t1.time_event < sysdate
and t2.event = 'enriched'
and t2.time_event > sysdate;

您还可以使用分析方法,这样您只需访问表一次,使用子查询将每个“丰富”时间与该 ID 的前一个“接受”时间配对,然后根据当前时间:

select to_char(date '1970-01-01'
  + nvl(max(sysdate - time_accepted), 0), 'HH24:MI:SS') as "current_age"
from (
  select last_value(case when event = 'accepted' then time_event end ignore nulls)
      over (partition by trax_id order by time_event) as time_accepted,
    case when event = 'enriched' then time_event end as time_enriched
  from tbl_dummyfeed
)
where time_accepted < sysdate
and time_enriched > sysdate;

【讨论】:

    【解决方案2】:

    这行得通,只需要转换为时间 hh24:mi:ss。

    SELECT max(CASE WHEN t1.time_event < SYSDATE and t2.time_event > SYSDATE THEN round((SYSDATE - t1.time_event) * 24 * 60 * 60) else 0 END) as "current_age"
        from tbl_dummyfeed t1 join tbl_dummyfeed t2 on t1.payment_id= t2.payment_id
        where t1.event = 'accepted' and t2.event = 'enriched';
    

    当我将转换添加到 hh24:mm:ss 解决方案是这样的

    SELECT to_char(to_date(max(CASE WHEN t1.time_event < SYSDATE and t2.time_event > SYSDATE THEN round((SYSDATE - t1.time_event) * 24 * 60
    * 60) else 0 END),'sssss'),'hh24:mi:ss') as "current_age" from tbl_dummyfeed t1 join tbl_dummyfeed t2 on t1.trax_Id = t2.trax_id where t1.event = 'accepted' and t2.event = 'enriched';
    

    这是解决我的问题的唯一好方法。希望这对人们有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-22
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多