【问题标题】:Difference Between two dates postgresql In Excel FormatExcel格式的两个日期postgresql之间的差异
【发布时间】:2016-10-31 00:33:29
【问题描述】:

您好,我想显示两个日期之间的 SQL 差异:
* END DATE = dt_termino / now()
* 开始日期 = dt_inicio

我有一个要在 CSV 中编写的函数...但在我的 csv 输出中,例如:

id_task_tarefa |      dt_inicio      |     dt_termino      |     sum
211            | 2016-01-25 10:40:25 | 2016-01-27 08:51:02 | 01 22:10:37
210            | 2016-01-25 10:40:29 | 2016-01-27 08:50:21 | 01 22:09:52

我需要在 Excel 中输出的格式 [h]:mm:ss;@ 像这样

id_task_tarefa |      dt_inicio      |     dt_termino      |    sum
211            | 2016-01-25 10:40:25 | 2016-01-27 08:51:02 | 46:10:37
210            | 2016-01-25 10:40:29 | 2016-01-27 08:50:21 | 46:09:52

这是我的 SQL:

SELECT id_task_tarefa, 
       dt_inicio, 
       dt_termino, 
       to_char(COALESCE(dt_termino::timestamp, now()::timestamp) 
             - dt_inicio::timestamp,'DD HH24:MI:SS')
FROM crm.task_interacao

【问题讨论】:

  • 考虑extract(epoch from timestamp1 - timestamp2) 返回两个时间戳之间的秒数。然后您可以使用简单的公式将其转换为小时、分钟和秒:x::int / (60*60) as h, x::int % (60*60) / 60 as m, x::int % 60 as s

标签: postgresql csv


【解决方案1】:

这个功能可能对你很方便:

create or replace function interval_in_hours(interval)
returns text language sql as $$
    select format('%s:%s',
        (extract (epoch from $1) / 3600)::int,
        to_char($1, 'mi:ss'))
$$;

用途:

with the_data (id_task_tarefa, dt_inicio, dt_termino) as (
    values
        (211, timestamp '2016-01-25 10:40:25', timestamp '2016-01-27 08:51:02'),
        (210, timestamp '2016-01-25 10:40:29', timestamp '2016-01-27 08:50:21') 
    )

select *, interval_in_hours(dt_termino- dt_inicio)::interval as sum
from the_data;

 id_task_tarefa |      dt_inicio      |     dt_termino      |   sum    
----------------+---------------------+---------------------+----------
            211 | 2016-01-25 10:40:25 | 2016-01-27 08:51:02 | 46:10:37
            210 | 2016-01-25 10:40:29 | 2016-01-27 08:50:21 | 46:09:52
(2 rows)

【讨论】:

  • 我想知道为什么你返回文本而不是返回间隔?现在我看到间隔显示正确的格式,将不同转换为间隔解决它容易吗?
  • 函数返回的文本类比to_char()format()等,改成interval也没问题。在示例中,我将结果转换为间隔以确保格式正确,但这当然是不必要的(我可以留下没有任何视觉差异的文本)。
  • 奇怪的部分是 '46:09:52'::interval 返回 46:09:52 而不是 01 22:10:37 在这种情况下,也许有办法将 (timestamp - timestamp)::interval 直接转换为我们想要的格式。
  • 没什么奇怪的,interval '20:00:00'+ interval '20:00:00' 给了'40:00:00'。有函数justify_hours() 来获取'1 day 16:00:00'。据我所知,没有(标准)反向功能。
  • 你怎么不觉得奇怪+产生40:00:00-产生01 22:10:37??
【解决方案2】:

不确定是否有更好的方法但有效

SELECT '2016-01-25 10:40:25' start_date, 
       '2016-01-27 08:51:02' end_date, 
       to_char('2016-01-27 08:51:02'::timestamp 
             - '2016-01-25 10:40:25'::timestamp,'HH24:MI:SS') as sum_text,
       TRUNC(EXTRACT(epoch FROM '2016-01-27 08:51:02'::timestamp - '2016-01-25 10:40:25'::timestamp)/3600)  time_diff,
       TRUNC(EXTRACT(epoch FROM '2016-01-27 08:51:02'::timestamp - '2016-01-25 10:40:25'::timestamp)/3600)  || ':' ||
       to_char('2016-01-27 08:51:02'::timestamp 
             - '2016-01-25 10:40:25'::timestamp,'MI:SS') result

输出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 2011-10-29
    相关资源
    最近更新 更多