简体   繁体   中英

PostgreSQL query to breakdown interval into weeks, days, hours, minutes, seconds

I am pretty inexperienced in PostgreSQL and am trying to get a row returning an interval from the current datetime to a given datetime as weeks, days, hours, minutes, and seconds broken down into separate columns.

The closest I've gotten other than a very convoluted solution is this:

SELECT

    (CURRENT_TIMESTAMP - '2021-01-01 00:00:00')::text AS str,
    
    SUBSTRING((CURRENT_TIMESTAMP - '2021-01-01 00:00:00')::text FROM  1 FOR 2)::NUMERIC AS days,
    SUBSTRING((CURRENT_TIMESTAMP - '2021-01-01 00:00:00')::text FROM  9 FOR 2)::NUMERIC AS hours,
    SUBSTRING((CURRENT_TIMESTAMP - '2021-01-01 00:00:00')::text FROM 12 FOR 2)::NUMERIC AS minutes,
    SUBSTRING((CURRENT_TIMESTAMP - '2021-01-01 00:00:00')::text FROM 15 FOR 2)::NUMERIC AS seconds

This gets me close: 在此处输入图像描述

My questions are:

  1. This implementation relies on the number of characters in the X days substring always being the same, which won't be true, so how do I make it more flexible?
  2. Can I save the result of (CURRENT_TIMESTAMP - '2021-01-01 00:00:00')::text to a simple variable so that I don't have to repeat it?
  3. How can I add a 'weeks' column and get 5 weeks, 5 days, ... instead of 40 days ?

I've looked at https://stackoverflow.com/a/56776697/2909854 , but I don't want months.

If I could just save the output of each result to a variable, I could do something relatively clean like this: https://stackoverflow.com/a/21323783/2909854

Any help is appreciated. Thanks!

You can use extract()

SELECT  (CURRENT_TIMESTAMP - '2021-01-01 00:00:00')::text AS str,
        extract(day from CURRENT_TIMESTAMP - '2021-01-01 00:00:00')as days,
        extract(hour from CURRENT_TIMESTAMP - '2021-01-01 00:00:00')as hours,
        extract(minute from CURRENT_TIMESTAMP - '2021-01-01 00:00:00')as minutes,
        extract(second from CURRENT_TIMESTAMP - '2021-01-01 00:00:00')as seconds;

To avoid repeating the expression you can use a common table expression :

with input (duration) as (
  values (CURRENT_TIMESTAMP - '2021-01-01 00:00:00')
)
select duration::text as str,
       extract(day from duration) as days, 
       extract(hour from duration) as hours,
       extract(minute from duration) as minutes,
       extract(second from duration) as seconds
from input;

You can't get "weeks" from an interval, but you can use justify_interval() to convert the days to months

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM