#python #sql #postgresql #psycopg2
#datetime #postgresql #интервалы
Вопрос:
Допустим, у меня есть интервал, подобный
4 days 10:00:00
в postgres. Как мне преобразовать это в количество часов (в данном случае 106?) Есть ли функция или я должен стиснуть зубы и сделать что-то вроде
extract(days, my_interval) * 24 extract(hours, my_interval)
Комментарии:
1. Примечание: Если ваш интервал содержит месяцы или годы, нет определенного ответа о том, сколько в нем часов, поскольку количество дней в месяце или году различается. Так что следите за этим!
2. @Teddy: Точнее, существует несколько определенных ответов 😉
Ответ №1:
Вероятно, самый простой способ — это:
SELECT EXTRACT(epoch FROM my_interval)/3600
Комментарии:
1. И, возможно, уменьшить или преобразовать результат в целое число, если интервал содержит минуты и / или секунды
2. Извлечь эпоху? О боже, это не пришло бы мне в голову и за миллион лет.
3. ВЫБЕРИТЕ ИЗВЛЕЧЕНИЕ (эпоха ИЗ my_interval / 3600) (интервал имеет встроенную поддержку ‘divide integer’, результат — интервал, а результат извлечения — целое число, а не число с плавающей точкой). Итак. Автокаст / Этаж выполнен.
4. Предупреждение: простое извлечение эпохи неявно предполагает, что один месяц = 30 дней и один год = 365,25 дней.
5. @Teddy что мы можем с этим сделать? Как избежать этой проблемы и получить реальное количество эпох?
Ответ №2:
Если вам нужно целое число, то есть количество дней:
SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int
Комментарии:
1. Отлично! Спасибо вам за это 🙂 Тем не менее, я обнаружил, что теперь мы можем изменить это на be
SELECT extract('epoch' FROM age('2014-08-02'::timestamp)) / 86400
(я использую Pg 9.4), посколькуage(ts)
автоматически использоватьCURRENT_DATE
только один аргумент.2. Предупреждение: простое извлечение эпохи неявно предполагает, что один месяц = 30 дней и один год = 365,25 дней.
Ответ №3:
Чтобы получить количество дней, самым простым способом было бы:
SELECT EXTRACT(DAY FROM NOW() - '2014-08-02 08:10:56');
Насколько я знаю, он вернет то же самое, что и:
SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int;
Комментарии:
1. Если ваш интервал равен
'1 month 0 days'
, использованиеextract(day from …)
даст вам0
результат.
Ответ №4:
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));
::int
Преобразование выполняется по принципу округления.
Если вы хотите получить другой результат, например, округление в меньшую сторону, вы можете использовать соответствующую математическую функцию, такую как floor
.
Ответ №5:
Если вы преобразуете поле таблицы:
-
Определите поле так, чтобы оно содержало секунды:
CREATE TABLE IF NOT EXISTS test ( ... field INTERVAL SECOND(0) );
-
Извлеките значение. Не забудьте привести к int в противном случае вы можете получить неприятный сюрприз, если интервалы будут большими:
EXTRACT(EPOCH FROM field)::int
Комментарии:
1. Я не думаю, что Redshift поддерживает тип данных ИНТЕРВАЛА. Это было бы просто BIGINT.
Ответ №6:
Если вы хотите отобразить свой результат только в типе даты после добавления интервала, попробуйте это
Выберите (current_date интервал ‘x day’)::дата;
Ответ №7:
Я работаю с PostgreSQL 11, и я создал функцию для получения часов между 2 разными временными метками
create function analysis.calcHours(datetime1 timestamp, datetime2 timestamp)
returns integer
language plpgsql as $$
declare
diff interval;
begin
diff = datetime2 - datetime1;
return (abs(extract(days from diff))*24 abs(extract(hours from diff)))::integer;
end; $$;
Ответ №8:
select date 'now()' - date '1955-12-15';
Вот простой запрос, который вычисляет общее количество дней.
Комментарии:
1. Это не принимает значение интервала.