Как определить наибольшее разрешение ИНТЕРВАЛА? - PullRequest
1 голос
/ 16 июня 2011

Как определить наибольшее разрешение значения ИНТЕРВАЛ?Например:

  • INTERVAL '100 days and 3 seconds' => день
  • TIME '20:05' - TIME '12:01:01' => час
  • AGE(NOW(), NOW() - INTERVAL '1 MONTH') => месяц

Ответы [ 2 ]

2 голосов
/ 16 июня 2011

Вопрос не ясен на 100%, поэтому ответ может быть, а может и нет, именно то, что вы ищете, но ...

Существует функция justify_interval(), которую вы, возможно, захотите изучить.

test=# select justify_interval(INTERVAL '100 days 3 seconds');
    justify_interval     
-------------------------
 3 mons 10 days 00:00:03
(1 row)

test=# select justify_interval(TIME '20:05' - TIME '12:01:01');
 justify_interval 
------------------
 08:03:59
(1 row)

test=# select justify_interval(AGE(NOW(), NOW() - INTERVAL '1 MONTH'));
 justify_interval 
------------------
 1 mon
(1 row)

Поскольку там извлекают год, затем месяц, затем день и т. Д., Пока вы не найдете ненулевой ответ:

test=# select extract('mon' from interval '3 mons 10 days 00:00:03');
 date_part 
-----------
         3

Re ваш другой вопрос в комментариях:

create function max_res(interval) returns interval as $$
select case
       when extract('year' from justify_interval($1)) > 0 or
            extract('mon' from justify_interval($1)) > 0 or
            extract('day' from justify_interval($1)) > 0
       then '1 day'
       when extract('hour' from justify_interval($1)) > 0
       then '1 hour'
       when ...
       end;
$$ language sql immutable strict;
1 голос
/ 16 июня 2011

INTERVAL имеет размер 12 байт и является структурой, содержащей месяцы, дни и микросекунды, и имеет диапазон +/- 178000000 лет. Он всегда имеет фиксированный максимальный размер 178000000 лет из-за способа хранения этой информации.

Будьте осторожны с вашим пониманием "месяца", потому что юлианский месяц не является константой так же, как hour или minute (например, сколько дней в месяце февраля? Или как сколько дней существует в year? В действительности это не всегда 30 или 365. В PostgreSQL все обновляется правильно. За один интересный разговор по IRC добавление 1 month :: INTERVAL к 30 января приведет к тому, что в последний день февраля потому что он увеличивает tm_mon член struct tm (и в этом случае выполняет откат к предыдущей действительной дате).


Ах, ха! У меня вопрос сейчас (или, по крайней мере, я так думаю). Вы пытаетесь определить наибольшую «ненулевую целочисленную единицу» для данного INTERVAL.

PostgreSQL не имеет встроенной функции, которая возвращает эту информацию. Я думаю, что вам придется связать условный и возвращаемый тип. Пример PL код:

t := EXTRACT(EPOCH FROM my_time_input);
IF t >= 31104000 THEN
  RETURN 'year';
ELSIF t >= 2592000 THEN
  RETURN 'month';
ELSIF t >= 604800 THEN
  RETURN 'week';
ELSIF t >= 86400 THEN
  RETURN 'day';
ELSIF t >= 3600 THEN
  RETURN 'hour';
ELSIF t >= 60 THEN
  RETURN 'minute'
ELSIF t > 1 THEN
  RETURN 'seconds';
ELSIF t == 1 THEN
  RETURN 'second';
ELSE
  RETURN resolve_largest_sub_second_unit(my_time);
END IF;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...