Документация по PostgreSQL 9.4.1 | |||
---|---|---|---|
Пред. | Уровень выше | Глава 9. Функции и операторы | След. |
9.9. Операторы и функции даты/времени
Все существующие функции для обработки даты/времени перечислены в Таблице 9-28, а подробнее они описаны в следующих подразделах. Поведение основных арифметических операторов (+, * и т. д.) описано в Таблице 9-27. Функции форматирования этих типов данных были перечислены в Разделе 9.8. Общую информацию об этих типах вы получили (или можете получить) в Разделе 8.5.
Все описанные ниже функции и операторы принимают две разновидности типов time или timestamp: с часовым поясом (time with time zone и timestamp with time zone) и без него (time without time zone и timestamp without time zone). Для краткости здесь они рассматриваются вместе. Кроме того, операторы + и * обладают переместительным свойством (например, date + integer = integer + date); здесь будет приведён только один вариант для каждой пары.
Таблица 9-27. Операторы даты/времени
Оператор | Пример | Результат |
---|---|---|
+ | date '2001-09-28' + integer '7' | date '2001-10-05' |
+ | date '2001-09-28' + interval '1 hour' | timestamp '2001-09-28 01:00:00' |
+ | date '2001-09-28' + time '03:00' | timestamp '2001-09-28 03:00:00' |
+ | interval '1 day' + interval '1 hour' | interval '1 day 01:00:00' |
+ | timestamp '2001-09-28 01:00' + interval '23 hours' | timestamp '2001-09-29 00:00:00' |
+ | time '01:00' + interval '3 hours' | time '04:00:00' |
- | - interval '23 hours' | interval '-23:00:00' |
- | date '2001-10-01' - date '2001-09-28' | integer '3' (дня) |
- | date '2001-10-01' - integer '7' | date '2001-09-24' |
- | date '2001-09-28' - interval '1 hour' | timestamp '2001-09-27 23:00:00' |
- | time '05:00' - time '03:00' | interval '02:00:00' |
- | time '05:00' - interval '2 hours' | time '03:00:00' |
- | timestamp '2001-09-28 23:00' - interval '23 hours' | timestamp '2001-09-28 00:00:00' |
- | interval '1 day' - interval '1 hour' | interval '1 day -01:00:00' |
- | timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00' | interval '1 day 15:00:00' |
* | 900 * interval '1 second' | interval '00:15:00' |
* | 21 * interval '1 day' | interval '21 days' |
* | double precision '3.5' * interval '1 hour' | interval '03:30:00' |
/ | interval '1 hour' / double precision '1.5' | interval '00:40:00' |
Таблица 9-28. Функции даты/времени
Функция | Тип результата | Описание | Пример | Результат |
---|---|---|---|---|
age(timestamp, timestamp) | interval | Вычитает аргументы и выдаёт "символический" результат с годами и месяцами, а не просто днями | age(timestamp '2001-04-10', timestamp '1957-06-13') | 43 years 9 mons 27 days (43 года 9 месяцев 27 дней) |
age(timestamp) | interval | Вычитает дату/время из current_date (полночь текущего дня) | age(timestamp '1957-06-13') | 43 years 8 mons 3 days (43 года 8 месяцев 3 дня) |
clock_timestamp() | timestamp with time zone | Текущая дата и время (меняется в процессе выполнения операторов); см. Подраздел 9.9.4 | ||
current_date | date | Текущая дата; см. Подраздел 9.9.4 | ||
current_time | time with time zone | Текущее время суток; см. Подраздел 9.9.4 | ||
current_timestamp | timestamp with time zone | Текущая дата и время (на момент начала транзакции); см. Подраздел 9.9.4 | ||
date_part(text, timestamp) | double precision | Возвращает поле даты (равнозначно extract ); см. Подраздел 9.9.1 | date_part('hour', timestamp '2001-02-16 20:38:40') | 20 |
date_part(text, interval) | double precision | Возвращает поле даты (равнозначно extract ); см. Подраздел 9.9.1 | date_part('month', interval '2 years 3 months') | 3 |
date_trunc(text, timestamp) | timestamp | Отсекает компоненты даты до заданной точности; см. также Подраздел 9.9.2 | date_trunc('hour', timestamp '2001-02-16 20:38:40') | 2001-02-16 20:00:00 |
date_trunc(text, interval) | interval | Отсекает компоненты даты до заданной точности; см. также Подраздел 9.9.2 | date_trunc('hour', interval '2 days 3 hours 40 minutes') | 2 days 03:00:00 |
extract (field from timestamp) | double precision | Возвращает поле даты; см. Подраздел 9.9.1 | extract(hour from timestamp '2001-02-16 20:38:40') | 20 |
extract (field from interval) | double precision | Возвращает поле даты; см. Подраздел 9.9.1 | extract(month from interval '2 years 3 months') | 3 |
isfinite(date) | boolean | Проверяет конечность даты (её отличие от +/-бесконечности) | isfinite(date '2001-02-16') | true |
isfinite(timestamp) | boolean | Проверяет конечность времени (его отличие от +/-бесконечности) | isfinite(timestamp '2001-02-16 21:28:30') | true |
isfinite(interval) | boolean | Проверяет конечность интервала | isfinite(interval '4 hours') | true |
justify_days(interval) | interval | Преобразует интервал так, что каждый 30-дневный период считается одним месяцем | justify_days(interval '35 days') | 1 mon 5 days (1 месяц 5 дней) |
justify_hours(interval) | interval | Преобразует интервал так, что каждый 24-часовой период считается одним днём | justify_hours(interval '27 hours') | 1 day 03:00:00 (1 день 03:00:00) |
justify_interval(interval) | interval | Преобразует интервал с применением justify_days и justify_hours и дополнительно корректирует знаки | justify_interval(interval '1 mon -1 hour') | 29 days 23:00:00 (29 дней 23:00:00) |
localtime | time | Текущее время суток; см. Подраздел 9.9.4 | ||
localtimestamp | timestamp | Текущая дата и время (на момент начала транзакции); см. Подраздел 9.9.4 | ||
make_date(year int, month int, day int) | date | Образует дату из полей: year (год), month (месяц) и day (день) | make_date(2013, 7, 15) | 2013-07-15 |
make_interval(years int DEFAULT 0, months int DEFAULT 0, weeks int DEFAULT 0, days int DEFAULT 0, hours int DEFAULT 0, mins int DEFAULT 0, secs double precision DEFAULT 0.0) | interval | Образует интервал из полей: years (годы), months (месяцы), weeks (недели), days (дни), hours (часы), minutes (минуты) и secs (секунды) | make_interval(days := 10) | 10 days |
make_time(hour int, min int, sec double precision) | time | Образует время из полей: hour (час), minute (минута) и sec (секунда) | make_time(8, 15, 23.5) | 08:15:23.5 |
make_timestamp(year int, month int, day int, hour int, min int, sec double precision) | timestamp | Образует дату и время из полей: year (год), month (месяц), day (день), hour (час), minute (минута) и sec (секунда) | make_timestamp(2013, 7, 15, 8, 15, 23.5) | 2013-07-15 08:15:23.5 |
make_timestamptz(year int, month int, day int, hour int, min int, sec double precision, [timezone text]) | timestamp with time zone | Образует дату и время с часовым поясом из полей: year (год), month (месяц), day (день), hour (час), minute (минута) и sec (секунда). Если параметр timezone (часовой пояс) не указан, используется текущий часовой пояс. | make_timestamptz(2013, 7, 15, 8, 15, 23.5) | 2013-07-15 08:15:23.5+01 |
now() | timestamp with time zone | Текущая дата и время (на момент начала транзакции); см. Подраздел 9.9.4 | ||
statement_timestamp() | timestamp with time zone | Текущая дата и время (на момент начала текущего оператора); см. Подраздел 9.9.4 | ||
timeofday() | text | Текущая дата и время (как clock_timestamp , но в виде строки типа text); см. Подраздел 9.9.4 | ||
transaction_timestamp() | timestamp with time zone | Текущая дата и время (на момент начала транзакции); см. Подраздел 9.9.4 |
В дополнение к этим функциям поддерживается SQL-оператор OVERLAPS:
(начало1, конец1) OVERLAPS (начало2, конец2) (начало1, длительность1) OVERLAPS (начало2, длительность2)
Его результатом будет true, когда два периода времени (определённые своими границами) пересекаются, и false в противном случае. Границы периода можно задать либо в виде пары дат, времени или дат со временем, либо как дату, время (или дату со временем) c интервалом. Когда указывается пара значений, первым может быть и начало, и конец периода: OVERLAPS автоматически считает началом периода меньшее значение. Периоды времени считаются наполовину открытыми, т. е. начало<=время<конец, если только начало и конец не равны — в этом случае период представляет один момент времени. Это означает, например, что два периода, имеющие только общую границу, не будут считаться пересекающимися.
SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS (DATE '2001-10-30', DATE '2002-10-30'); Результат:true SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS (DATE '2001-10-30', DATE '2002-10-30'); Результат:false SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS (DATE '2001-10-30', DATE '2001-10-31'); Результат:false SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS (DATE '2001-10-30', DATE '2001-10-31'); Результат:true
При добавлении к дате со временем типа timestamp with time zone значения interval (или при вычитании из него interval), поле дней в этой дате увеличивается (или уменьшается) на указанное число дней. При пересечении границы перехода на летнее время (если в часовом поясе текущего сеанса производится этот переход) это означает, что interval '1 day' и interval '24 hours' не обязательно будут равны. Например, в часовом поясе CST7CDT результатом выражения timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' будет timestamp with time zone '2005-04-03 12:00-06', тогда как, если добавить interval '24 hours' к тому же значению timestamp with time zone, в результате получится timestamp with time zone '2005-04-03 13:00-06'. Эта разница объясняется тем, что 2005-04-03 02:00 в часовом поясе CST7CDT произошёл переход на летнее время.
Обратите внимание на возможную неоднозначность в поле months в результате функции age
, вызванную тем, что число дней в разных месяцах неодинаково. Вычисляя оставшиеся дни месяца, PostgreSQL рассматривает месяц меньшей из двух дат. Например, результатом age('2004-06-01', '2004-04-30') будет 1 mon 1 day, так как в апреле 30 дней, а то же выражение с датой 30 мая выдаст 1 mon 2 days, так как в мае 31 день.
Вычитание дат и дат со временем также может быть нетривиальной операцией. Один принципиально простой способ выполнить такое вычисление — преобразовать каждое значение в количество секунд, используя EXTRACT(EPOCH FROM ...), а затем найти разницу результатов; при этом будет получено число секунд между двумя датами. При этом будет учтено неодинаковое число дней в месяцах, изменения часовых поясов и переходы на летнее время. При вычитании дат или дат со временем с помощью оператора "-" выдаётся число дней (по 24 часа) и часов/минут/секунд между данными значениями, с учётом тех же факторов. Функция age
возвращает число лет, месяцев, дней и часов/минут/секунд, выполняя вычитание по полям, а затем пересчитывая отрицательные значения. Различие этих подходов иллюстрируют следующие запросы. Показанные результаты были получены для часового пояса 'US/Eastern'; между двумя заданными датами произошёл переход на летнее время:
SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') - EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'); Результат:10537200 SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') - EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00')) / 60 / 60 / 24; Результат:121.958333333333 SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00'; Результат:121 days 23:00:00 SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00'); Результат:4 mons
9.9.1. EXTRACT
, date_part
EXTRACT(field FROM source)
Функция extract
получает из значений даты/времени поля, такие как год или час. Здесь источник — значение типа timestamp, time или interval. (Выражения типа date приводятся к типу timestamp, так что допускается и этот тип.) Указанное поле представляет собой идентификатор, по которому из источника выбирается заданное поле. Функция extract
возвращает значения типа double precision. Допустимые поля:
- century
Век:
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13'); Результат:20 SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:21
Первый век начался 0001-01-01 00:00:00, хотя люди в то время и не считали так. Это определение распространяется на все страны с григорианским календарём. Века с номером 0 нет было; считается, что 1 наступил после -1. Если такое положение вещей вас не устраивает, направляйте жалобы по адресу: Ватикан, Собор Святого Петра, Папе.
- day
Для значений timestamp это день месяца (1 - 31), для значений interval — число дней
SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:16 SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute'); Результат:40
- decade
Год, делённый на 10
SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:200
- dow
День недели, считая с воскресенья (0) до субботы (6)
SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:5
Заметьте, что в
extract
дни недели нумеруются не так, как в функцииto_char(..., 'D')
.- doy
День года (1 - 365/366)
SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:47
- epoch
Для значений timestamp with time zone это число секунд с 1970-01-01 00:00:00 UTC (может быть отрицательным); для значений date и timestamp это число секунд с 1970-01-01 00:00:00 по местному времени, а для interval — общая длительность интервала в секундах
SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08'); Результат:982384720.12 SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours'); Результат:442800
Преобразовать время эпохи назад, в значение дата/время можно так:
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 982384720.12 * INTERVAL '1 second';
(Это преобразование осуществляет функция
to_timestamp
.)- hour
Час (0 - 23)
SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:20
- isodow
День недели, считая с понедельника (1) до воскресенья (7)
SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40'); Результат:7
Результат отличается от dow только для воскресенья. Такая нумерация соответствует ISO 8601.
- isoyear
Год по недельному календарю ISO 8601, в который попадает дата (неприменимо к интервалам)
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01'); Результат:2005 SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); Результат:2006
Год по недельному календарю ISO начинается с понедельника недели, в которой оказывается 4 января, так что в начале января или в конце декабря год по ISO может отличаться от года по григорианскому календарю. Подробнее об этом рассказывается в описании поля week.
Этого поля не было в PostgreSQL до версии 8.3.
- microseconds
Значение секунд с дробной частью, умноженное на 1 000 000; заметьте, что оно включает и целые секунды
SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); Результат:28500000
- millennium
Тысячелетие
SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:3
Годы 20 века относятся ко второму тысячелетию. Третье тысячелетие началось 1 января 2001 г.
- milliseconds
Значение секунд с дробной частью, умноженное на 1 000; заметьте, что оно включает и целые секунды.
SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5'); Результат:28500
- minute
Минуты (0 - 59)
SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:38
- month
Для значений timestamp это номер месяца в году (1 - 12), а для interval — остаток от деления числа месяцев на 12 (в интервале 0 - 11)
SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:2 SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months'); Результат:3 SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); Результат:1
- quarter
Квартал года (1 - 4), к которому относится дата
SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:1
- second
Секунды, включая дробную часть (0 - 59[1])
SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:40 SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); Результат:28.5
- timezone
Смещение часового пояса от UTC, представленное в секундах. Положительные значения соответствуют часовым поясам к востоку от UTC, а отрицательные — к западу. (Выражаясь технически точно, PostgreSQL использует UT1, так как секунды координации не учитываются.)
- timezone_hour
Поле часов в смещении часового пояса
- timezone_minute
Поле минут в смещении часового пояса
- week
Номер недели в году по недельному календарю ISO 8601. По определению, недели ISO 8601 начинаются с понедельника, а первая неделя года включает 4 января этого года. Другими словами, первый четверг года всегда оказывается в 1 неделе этого года.
В системе нумерации недель ISO первые числа января могут относиться к 52-ой или 53-ей неделе предыдущего года, а последние числа декабря — к первой неделе следующего года. Например, 2005-01-01 относится к 53-ей неделе 2004 г., а 2006-01-01 — к 52-ей неделе 2005 г., тогда как 2012-12-31 включается в первую неделю 2013 г. Поэтому для получения согласованных результатов рекомендуется использовать поле isoyear в паре с week.
SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:7
- year
Поле года. Учтите, что года 0 не было, и это следует иметь в виду, вычитая из годов нашей эры годы до нашей эры.
SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:2001
Функция extract
в основном предназначена для вычислительных целей. Функции форматирования даты/времени описаны в Разделе 9.8.
Функция date_part
эмулирует традиционный для Ingres эквивалент стандартной SQL-функции extract
:
date_part('поле', источник)
Заметьте, что здесь параметр поле должен быть строковым значением, а не именем. Функция date_part
воспринимает те же поля, что и extract
.
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40'); Результат:16 SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); Результат:4
9.9.2. date_trunc
Функция date_trunc
работает подобно trunc
для чисел.
date_trunc('поле', значение)
Здесь значение — это выражение типа timestamp или interval. (Значения типов date и time автоматически приводятся к типам timestamp и interval, соответственно.) Параметр поле определяет, до какой точности обрезать переданное значение. Возвращаемое значение будет иметь тип timestamp или interval и все его значения, менее значимые, чем заданное поле, будут равны нулю (или единице, если это номер дня или месяца).
Параметр поле может принимать следующие значения:
microseconds |
milliseconds |
second |
minute |
hour |
day |
week |
month |
quarter |
year |
decade |
century |
millennium |
Примеры:
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40'); Результат: 2001-02-16 20:00:00 SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); Результат: 2001-01-01 00:00:00
9.9.3. AT TIME ZONE
Конструкция AT TIME ZONE позволяет переводить время в разные часовые пояса. Все её разновидности показаны в Таблице 9-29.
Таблица 9-29. Разновидности AT TIME ZONE
Выражение | Тип результата | Описание |
---|---|---|
timestamp without time zone AT TIME ZONE часовой_пояс | timestamp with time zone | Воспринимает заданное время без указания часового пояса как время в указанном часовом поясе |
timestamp with time zone AT TIME ZONE часовой_пояс | timestamp without time zone | Переводит данное значение timestamp с часовым поясом в другой часовой пояс, но не сохраняет информацию о нём в результате |
time with time zone AT TIME ZONE часовой_пояс | time with time zone | Переводит данное время с часовым поясом в другой часовой пояс |
В этих выражениях желаемый часовой_пояс можно задать либо в виде текстовой строки (например, 'PST') или как интервал (например, INTERVAL '-08:00'). В первом случае название часового пояса можно указать любым из способов, описанных в Подразделе 8.5.3.
Примеры (в предположении, что местный часовой пояс PST8PDT):
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST'; Результат: 2001-02-16 19:38:40-08 SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST'; Результат: 2001-02-16 18:38:40
В первом примере время без часового пояса интерпретируется как время в часовом поясе MST (UTC-7), а затем оно преобразуется в PST (UTC-8) для вывода. Во втором примере время, указанное с часовым поясом EST (UTC-5), преобразуется во время для часового пояса MST (UTC-7).
Функция timezone
(часовой_пояс, время) равнозначна SQL-совместимой конструкции время AT TIME ZONE часовой_пояс.
9.9.4. Текущая дата/время
PostgreSQL предоставляет набор функций, результат которых зависит от текущей даты и времени. Все следующие функции соответствуют стандарту SQL и возвращают значения, отражающие время начала текущей транзакции:
CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_TIME(точность) CURRENT_TIMESTAMP(точность) LOCALTIME LOCALTIMESTAMP LOCALTIME(точность) LOCALTIMESTAMP(точность)
CURRENT_TIME
и CURRENT_TIMESTAMP
возвращают время с часовым поясом. В результатах LOCALTIME
и LOCALTIMESTAMP
нет информации о часовом поясе.
CURRENT_TIME
, CURRENT_TIMESTAMP
, LOCALTIME
и LOCALTIMESTAMP
могут принимать необязательный параметр точности, определяющий, до какого знака после запятой следует округлять поле секунд. Если этот параметр отсутствует, результат будет иметь максимально возможную точность.
Несколько примеров:
SELECT CURRENT_TIME; Результат: 14:39:53.662522-05 SELECT CURRENT_DATE; Результат: 2001-12-23 SELECT CURRENT_TIMESTAMP; Результат: 2001-12-23 14:39:53.662522-05 SELECT CURRENT_TIMESTAMP(2); Результат: 2001-12-23 14:39:53.66-05 SELECT LOCALTIMESTAMP; Результат: 2001-12-23 14:39:53.662522
Так как эти функции возвращают время начала текущей транзакции, во время транзакции эти значения не меняются. Это считается не ошибкой, а особенностью реализации: цель такого поведения в том, чтобы в одной транзакции "текущее" время было одинаковым и для разных изменений в одной транзакций записывалась одна отметка времени.
Замечание: В других СУБД эти значения могут изменяться чаще.
В PostgreSQL есть также функции, возвращающие время начала текущего оператора, а также текущее время в момент вызова функции. Таким образом, в PostgreSQL есть следующие функции, не описанные в стандарте SQL:
transaction_timestamp() statement_timestamp() clock_timestamp() timeofday() now()
Функция transaction_timestamp()
равнозначна конструкции CURRENT_TIMESTAMP
, но в её названии явно отражено, что она возвращает. Функция statement_timestamp()
возвращает время начала текущего оператора (более точно, время получения последнего командного сообщения от клиента). Функции statement_timestamp()
и transaction_timestamp()
возвращают одно и то же значение в первой команде транзакции, но в последующих их показания будут расходиться. Функция clock_timestamp()
возвращает фактическое текущее время, так что её значение меняется в рамках одной команды SQL. Функция timeofday()
существует в PostgreSQL по историческим причинам и, подобно clock_timestamp()
, она возвращает фактическое текущее время, но представленное в виде форматированной строки типа text, а не значения timestamp with time zone. Функция now()
— традиционный для PostgreSQL эквивалент функции transaction_timestamp()
.
Все типы даты/времени также принимают специальное буквальное значение now, подразумевающее текущую дату и время (тоже на момент начала транзакции). Таким образом, результат следующих трёх операторов будет одинаковым:
SELECT CURRENT_TIMESTAMP; SELECT now(); SELECT TIMESTAMP 'now'; -- не подходит для DEFAULT
Подсказка: Третья форма не подходит для указания в качестве значения DEFAULT при создании таблицы. Система преобразует now в значение timestamp в момент разбора константы, поэтому, когда будет вставляться значение по умолчанию, в соответствующей колонке окажется время создания таблицы! Первые две формы не будут вычисляться, пока не потребуется значение по умолчанию, так как это вызовы функции. Поэтому они дадут желаемый результат при добавлении строки в таблицу.
9.9.5. Задержка выполнения
В случае необходимости вы можете приостановить выполнение серверного процесса, используя следующие функции:
pg_sleep(сек) pg_sleep_for(interval) pg_sleep_until(timestamp with time zon)
Функция pg_sleep
переводит процесс текущего сеанса в спящее состояние на указанное число секунд (сек). Параметр сек имеет тип double precision, так что в нём можно указать и дробное число. Функция pg_sleep_for
введена для удобства, ей можно передать большие значения задержки в типе interval. А pg_sleep_until
удобнее использовать, когда необходимо задать определённое время выхода из спящего состояния. Например:
SELECT pg_sleep(1.5); SELECT pg_sleep_for('5 minutes'); SELECT pg_sleep_until('tomorrow 03:00');
Замечание: Действительное разрешение интервала задержки зависит от платформы; обычно это 0.01. Фактическая длительность задержки не будет меньше указанного времени, но может быть больше, в зависимости, например от нагрузки на сервер. В частности, не гарантируется, что
pg_sleep_until
проснётся именно в указанное время, но она точно не проснётся раньше.
Внимание |
Прежде чем вызывать |
Примечания
[1] | 60, если операционная система поддерживает секунды координации |
Пред. | Начало | След. |
Функции форматирования данных | Уровень выше | Функции для перечислений |
9.23. Row and Array Comparisons
This section describes several specialized constructs for making multiple comparisons between groups of values. These forms are syntactically related to the subquery forms of the previous section, but do not involve subqueries. The forms involving array subexpressions are Postgres Pro extensions; the rest are SQL-compliant. All of the expression forms documented in this section return Boolean (true/false) results.
9.23.1. IN
expression
IN (value
[, ...])
The right-hand side is a parenthesized list of expressions. The result is “true” if the left-hand expression's result is equal to any of the right-hand expressions. This is a shorthand notation for
expression
=value1
ORexpression
=value2
OR ...
Note that if the left-hand expression yields null, or if there are no equal right-hand values and at least one right-hand expression yields null, the result of the IN
construct will be null, not false. This is in accordance with SQL's normal rules for Boolean combinations of null values.
9.23.2. NOT IN
expression
NOT IN (value
[, ...])
The right-hand side is a parenthesized list of expressions. The result is “true” if the left-hand expression's result is unequal to all of the right-hand expressions. This is a shorthand notation for
expression
<>value1
ANDexpression
<>value2
AND ...
Note that if the left-hand expression yields null, or if there are no equal right-hand values and at least one right-hand expression yields null, the result of the NOT IN
construct will be null, not true as one might naively expect. This is in accordance with SQL's normal rules for Boolean combinations of null values.
Tip
x NOT IN y
is equivalent to NOT (x IN y)
in all cases. However, null values are much more likely to trip up the novice when working with NOT IN
than when working with IN
. It is best to express your condition positively if possible.
9.23.3. ANY
/SOME
(array)
expression
operator
ANY (array expression
)expression
operator
SOME (array expression
)
The right-hand side is a parenthesized expression, which must yield an array value. The left-hand expression is evaluated and compared to each element of the array using the given operator
, which must yield a Boolean result. The result of ANY
is “true” if any true result is obtained. The result is “false” if no true result is found (including the case where the array has zero elements).
If the array expression yields a null array, the result of ANY
will be null. If the left-hand expression yields null, the result of ANY
is ordinarily null (though a non-strict comparison operator could possibly yield a different result). Also, if the right-hand array contains any null elements and no true comparison result is obtained, the result of ANY
will be null, not false (again, assuming a strict comparison operator). This is in accordance with SQL's normal rules for Boolean combinations of null values.
SOME
is a synonym for ANY
.
9.23.4. ALL
(array)
expression
operator
ALL (array expression
)
The right-hand side is a parenthesized expression, which must yield an array value. The left-hand expression is evaluated and compared to each element of the array using the given operator
, which must yield a Boolean result. The result of ALL
is “true” if all comparisons yield true (including the case where the array has zero elements). The result is “false” if any false result is found.
If the array expression yields a null array, the result of ALL
will be null. If the left-hand expression yields null, the result of ALL
is ordinarily null (though a non-strict comparison operator could possibly yield a different result). Also, if the right-hand array contains any null elements and no false comparison result is obtained, the result of ALL
will be null, not true (again, assuming a strict comparison operator). This is in accordance with SQL's normal rules for Boolean combinations of null values.
9.23.5. Row Constructor Comparison
row_constructor
operator
row_constructor
Each side is a row constructor, as described in Section 4.2.13. The two row constructors must have the same number of fields. The given operator
is applied to each pair of corresponding fields. (Since the fields could be of different types, this means that a different specific operator could be selected for each pair.) All the selected operators must be members of some B-tree operator class, or be the negator of an =
member of a B-tree operator class, meaning that row constructor comparison is only possible when the operator
is =
, <>
, <
, <=
, >
, or >=
, or has semantics similar to one of these.
The =
and <>
cases work slightly differently from the others. Two rows are considered equal if all their corresponding members are non-null and equal; the rows are unequal if any corresponding members are non-null and unequal; otherwise the result of the row comparison is unknown (null).
For the <
, <=
, >
and >=
cases, the row elements are compared left-to-right, stopping as soon as an unequal or null pair of elements is found. If either of this pair of elements is null, the result of the row comparison is unknown (null); otherwise comparison of this pair of elements determines the result. For example, ROW(1,2,NULL) < ROW(1,3,0)
yields true, not null, because the third pair of elements are not considered.
Note
Prior to PostgreSQL 8.2, the <
, <=
, >
and >=
cases were not handled per SQL specification. A comparison like ROW(a,b) < ROW(c,d)
was implemented as a < c AND b < d
whereas the correct behavior is equivalent to a < c OR (a = c AND b < d)
.
row_constructor
IS DISTINCT FROMrow_constructor
This construct is similar to a <>
row comparison, but it does not yield null for null inputs. Instead, any null value is considered unequal to (distinct from) any non-null value, and any two nulls are considered equal (not distinct). Thus the result will either be true or false, never null.
row_constructor
IS NOT DISTINCT FROMrow_constructor
This construct is similar to a =
row comparison, but it does not yield null for null inputs. Instead, any null value is considered unequal to (distinct from) any non-null value, and any two nulls are considered equal (not distinct). Thus the result will always be either true or false, never null.
9.23.6. Composite Type Comparison
record
operator
record
The SQL specification requires row-wise comparison to return NULL if the result depends on comparing two NULL values or a NULL and a non-NULL. Postgres Pro does this only when comparing the results of two row constructors (as in Section 9.23.5) or comparing a row constructor to the output of a subquery (as in Section 9.22). In other contexts where two composite-type values are compared, two NULL field values are considered equal, and a NULL is considered larger than a non-NULL. This is necessary in order to have consistent sorting and indexing behavior for composite types.
Each side is evaluated and they are compared row-wise. Composite type comparisons are allowed when the operator
is =
, <>
, <
, <=
, >
or >=
, or has semantics similar to one of these. (To be specific, an operator can be a row comparison operator if it is a member of a B-tree operator class, or is the negator of the =
member of a B-tree operator class.) The default behavior of the above operators is the same as for IS [ NOT ] DISTINCT FROM
for row constructors (see Section 9.23.5).
To support matching of rows which include elements without a default B-tree operator class, the following operators are defined for composite type comparison: *=
, *<>
, *<
, *<=
, *>
, and *>=
. These operators compare the internal binary representation of the two rows. Two rows might have a different binary representation even though comparisons of the two rows with the equality operator is true. The ordering of rows under these comparison operators is deterministic but not otherwise meaningful. These operators are used internally for materialized views and might be useful for other specialized purposes such as replication and B-Tree deduplication (see Section 63.4.2). They are not intended to be generally useful for writing queries, though.