Jak przekonwertować interwał na liczbę godzin za pomocą postgresów?

161

Powiedz, że mam przerwę w stylu

4 days 10:00:00

w postgres. Jak przekonwertować to na liczbę godzin (w tym przypadku 106?) Czy jest funkcja, czy powinienem ugryźć kulę i zrobić coś takiego

extract(days, my_interval) * 24 + extract(hours, my_interval)
agnul
źródło
9
Uwaga: jeśli interwał zawiera miesiące lub lata, nie ma zdefiniowanej odpowiedzi na temat liczby godzin, ponieważ liczba dni w miesiącu lub roku jest różna. Więc uważaj na to!
Teddy

Odpowiedzi:

314

Prawdopodobnie najłatwiejszym sposobem jest:

SELECT EXTRACT(epoch FROM my_interval)/3600
Magnus Hagander
źródło
6
I może podłoga lub rzut wyniku na liczbę całkowitą, jeśli interwał zawiera minuty i / lub sekundy
rasjani
64
Wydobyć epokę? Ojej, to nie przyszłoby mi do głowy za milion lat.
agnul
5
SELECT EXTRACT (epoch FROM my_interval / 3600) (interwał ma natywną obsługę „dzielenia liczby całkowitej”, wynikiem jest przedział, a wynik wyodrębniania jest liczbą całkowitą, a nie liczbą zmiennoprzecinkową). Więc. Autocast / Floor gotowe.
Offenso
19
Ostrzeżenie: proste wyodrębnienie epoki zakłada niejawnie, że jeden miesiąc = 30 dni, a jeden rok = 365,25 dni.
Teddy
@Teddy co możemy z tym zrobić? Jak uniknąć tego problemu i uzyskać rzeczywistą liczbę epok?
Asmox
18

Jeśli chcesz liczbę całkowitą, czyli liczbę dni:

SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int
Pujan Srivastava
źródło
Wspaniały! Dziękuję za to :) Jednak odkryłem, że możemy teraz zmodyfikować to na SELECT extract('epoch' FROM age('2014-08-02'::timestamp)) / 86400(używam strony 9.4), ponieważ age(ts)automatycznie używamy CURRENT_DATEtylko jednego argumentu.
1111161171159459134
7
Ostrzeżenie: proste wyodrębnienie epoki zakłada niejawnie, że jeden miesiąc = 30 dni, a jeden rok = 365,25 dni.
Teddy
3

Najłatwiejszym sposobem uzyskania liczby dni byłoby:

SELECT EXTRACT(DAY FROM NOW() - '2014-08-02 08:10:56');

O ile wiem, zwróci to tak samo, jak:

SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int;
belveryin
źródło
27
Jeśli Twój interwał to '1 month 0 days', użycie extract(day from …)da ci 0wynik.
Underyx
1
select floor((date_part('epoch', order_time - '2016-09-05 00:00:00') / 3600)), count(*)
from od_a_week
group by floor((date_part('epoch', order_time - '2016-09-05 00:00:00') / 3600));

::intKonwersji stosuje zasadę zaokrąglania. Jeśli chcesz uzyskać inny wynik, na przykład zaokrąglając w dół, możesz użyć odpowiedniej funkcji matematycznej, takiej jak floor.

haoming
źródło
1

Jeśli konwertujesz pole tabeli:

  1. Zdefiniuj pole tak, aby zawierało sekundy:

     CREATE TABLE IF NOT EXISTS test (
         ...
         field        INTERVAL SECOND(0)
     );
  2. Wyodrębnij wartość. Pamiętaj, aby rzucać tak, aby w przeciwnym razie możesz otrzymać niemiłą niespodziankę, gdy interwały będą duże:

    EXTRACT(EPOCH FROM field)::int

Janek Olszak
źródło
Nie sądzę, aby Redshift obsługuje typ danych INTERVAL. To byłoby po prostu DUŻE.
matt2000
-4
         select date 'now()' - date '1955-12-15';

Oto proste zapytanie, które oblicza całkowitą liczbę dni.

Arunkumar Papena
źródło
4
To nie przyjmuje wartości interwału.
Teddy