– (вычитание) (Transact-SQL)
Вычитает одно число из другого (оператор арифметического вычитания). Также можно вычесть из даты определенное число дней.
Синтаксис
expression - expression
Сведения о синтаксисе Transact-SQL для SQL Server 2014 (12.x) и более ранних версиях см . в документации по предыдущим версиям.
Аргументы
выражение
Любое допустимое выражение expression любого числового типа данных, кроме bit. Нельзя использовать с типами данных date, time, datetime2 или datetimeoffset.
Типы результата
Возвращает результат типа данных аргумента с более высоким приоритетом. Дополнительные сведения см. в разделе Приоритет типов данных (Transact-SQL).
Примеры
А. Использование вычитания в инструкции SELECT
Следующий пример вычисляет разницу налоговых ставок между штатом или провинцией с наибольшей налоговой ставкой и штатом или провинцией с наименьшей налоговой ставкой.
Применимо к: SQL Server и База данных SQL.
-- Uses AdventureWorks SELECT MAX(TaxRate) - MIN(TaxRate) AS 'Tax Rate Difference' FROM Sales.SalesTaxRate WHERE StateProvinceID IS NOT NULL; GO
Можно изменить порядок выполнения, используя скобки. Сначала производятся вычисления выражений в скобках. В случае вложенных скобок вычисления начинаются с самого глубокого уровня.
B. Использование вычитания из даты
Следующий пример вычитает указанное число дней из даты datetime .
Применимо к: SQL Server и База данных SQL.
-- Uses the AdventureWorks sample database DECLARE @altstartdate DATETIME; SET @altstartdate = CONVERT(DATETIME, 'January 10, 1900 3:00 AM', 101); SELECT @altstartdate - 1.5 AS 'Subtract Date';
Subtract Date ----------------------- 1900-01-08 15:00:00.000 (1 row(s) affected)
Примеры: Azure Synapse Analytics и система платформы аналитики (PDW)
В. Использование вычитания в инструкции SELECT
В следующем примере вычисляется разница базовых окладов между сотрудником с наибольшим базовым окладом и сотрудником с наименьшей налоговой ставкой из таблицы dimEmployee .
-- Uses AdventureWorks SELECT MAX(BaseRate) - MIN(BaseRate) AS BaseRateDifference FROM DimEmployee;
Как от даты отнять год, месяц, день?
где, Data — дата от которой нужно отнять кол-во Y — лет, М — месяцев, D — дней, и получившееся в результате число записать в Data_N. (если как в примере: 01.11.2015 — 4 года — 3 месяца — 5 дней = 27.07.2011
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Как изменить год в поле дата не меняя месяц и число
Помогите кто может. Как изменить год в поле дата не меняя месяц и число с помощью FoxPro 2.6.
Как в maskedit с форматом даты увеличить ее на год, месяц или день?
Есть маскэдит. Маска ввода Дата. Надо чтобы при нажатии на кнопку эта дата увеличивалась. Надо.

Отсортировать даты по 4 параметрам: год, месяц, день, время
Есть даты такого формата: Fri, 28 Mar 2014 16:42:58 PDT Fri, 28 Mar 2014 15:16:47 PDT Sat, 29.
Дан строковый файл, содержащий даты в формате «день/месяц/год»
Дан строковый файл, содержащий даты в формате «день/месяц/год», причем под день и месяц отводится.
4214 / 3054 / 582
Регистрация: 21.01.2011
Сообщений: 13,205
Сообщение от deret24 
Подскажите, как получить Data_N
отнять год
SELECT ADD_MONTHS(to_date('01.01.2015', 'dd.mm.yyyy'), -12) FROM dual
763 / 664 / 195
Регистрация: 24.11.2015
Сообщений: 2,158
В Oracle есть две функции: NUMTOYMINTERVAL (интервал год-месяц) и NUMTODSINTERVAL (интервал день-секунда). С их помошью можно записать:
1 2 3 4 5
SELECT to_date('20150101','yyyymmdd') - NUMTOYMINTERVAL(5, 'year') - NUMTOYMINTERVAL(3, 'month') - NUMTODSINTERVAL(7, 'day') FROM dual;
Если заданы только месяцы, то лучше всего пользоваться функцией
Сообщение от Grossmeister 
ADD_MONTHS
Если заданы только дни, то можно их просто прибавить к дате или отнять от даты:
SELECT to_date('20150101','yyyymmdd') - 17 FROM dual;
267 / 231 / 78
Регистрация: 16.12.2015
Сообщений: 943
Записей в блоге: 4
Я бы делал в общем виде, но по сути AGK уже решение подсказал
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
DECLARE p_yy NUMBER; p_mm NUMBER; p_dd NUMBER; p_date DATE; p_res CHAR(10); BEGIN SELECT '&"Исходная дата - в формате dd.mm.yyyy - "' INTO p_date FROM dual; SELECT &"Сколько нужно вычесть лет - " INTO p_yy FROM dual; SELECT &"Сколько нужно вычесть месяцев - " INTO p_mm FROM dual; SELECT &"Сколько нужно вычесть дней - " INTO p_dd FROM dual; SELECT to_char(p_date - NUMTOYMINTERVAL(p_yy, 'year') - NUMTOYMINTERVAL(p_mm, 'month') - NUMTODSINTERVAL(p_dd, 'day')), 'dd.mm.yyyy') INTO p_res FROM dual; dbms_output.put_line(p_res); END;
763 / 664 / 195
Регистрация: 24.11.2015
Сообщений: 2,158
Все верно, но не факт, что требуется вводить данные с клавиатуры, а потом выводить на консоль (экран). Возможно, требуется каким-то образом обработать содержимое нескольких таблиц и результат запихнуть еще в одну таблицу. Так что Ваше
Сообщение от Meridian21 
Я бы делал в общем виде
на самом деле есть очень и очень частный случай, а совсем не общий вид. Так что сойдемся на том, что Вы привели пример использования.
У меня, собственно, тоже всего лишь пример использования, но без наворотов, связанных с консольным вводом и выводом
Регистрация: 08.07.2015
Сообщений: 16
Сообщение от Meridian21 
SELECT ‘&»Исходная дата — в формате dd.mm.yyyy — «‘
Дело в том что в данной таблице много записей, как в запросе SELECT указать чтоб поле Data_N всё заполнилось автоматически?
763 / 664 / 195
Регистрация: 24.11.2015
Сообщений: 2,158
Сообщение от deret24 
поле Data_N всё заполнилось автоматически
Есть два способа:
1) Открывается курсор, в котором собираются все исходные данные, затем в цикле по курсору делается UPDATE нужного поля.
2) Пишется сложный оператор UPDATE, в котором и происходит корректировка данных.
Попробуйте почитать про курсоры и написать какой-нибудь пример курсора, потом будем подправлять
Регистрация: 08.07.2015
Сообщений: 16
беру перерывчик, прихворал я
763 / 664 / 195
Регистрация: 24.11.2015
Сообщений: 2,158
В простом случае вроде Вашего, когда все поля в одной таблице, лучше сразу писать UPADTE вида
1 2 3
UPADTE "TABLE_NAME" SET DATA_N = "FUNCTION_ON_TABLE_FIELDS" WHERE "LIMITATION_CONDITION";
Добавлено через 30 минут
Если у Вас есть несколько таблиц, из которых нужно собрать данные, номер с апдейтом обычно не проходит
Регистрация: 08.07.2015
Сообщений: 16
Сообщение от AGK 
Если у Вас есть несколько таблиц, из которых нужно собрать данные, номер с апдейтом обычно не проходит
таблица одна, а наведённые поля её часть, это, грубо говоря, таблица содержащая данные по работникам (много работников), со стажем (это те самые Y M D) на число (data) и нужно «заполнить» дату с которой начинается стаж (data_N) по всей этой таблице. Я не могу «подобрать» что бы работала запись вида t.data_N = t.data — t.Y — t.M -t.D, как говориться, моя понимать, что нужно в цикле в процедуре\функции это запускать
763 / 664 / 195
Регистрация: 24.11.2015
Сообщений: 2,158

Сообщение было отмечено deret24 как решение
Решение
Сообщение от deret24 
то нужно в цикле . это запускать
Да не нужно в цикле. В отличие от алгоритмических языков здесь нужно работать блоками. Голова должна начать работать по-другому, это не сразу получается, по себе помню. Вы просто пишете один апдейт, и он в одном заходе выполняет все нужные действия. Цикл у Вас спрятан внутри, он на низком уровне, в отличие от реализации на алгоритмическом языке. Пишете
1 2 3 4 5
UPADTE "TABLE_NAME" SET DATA_N = DATA- NUMTOYMINTERVAL(Y, 'year') - NUMTOYMINTERVAL(M, 'month') - NUMTODSINTERVAL(D, 'day') WHERE "LIMITATION_CONDITION";
Добавлено через 3 минуты
По поводу «LIMITATION_CONDITION». Например, Вы хотите заполнять только те даты, которые еще не заполнены. Тогда в качестве where_clause следует писать
WHERE DATA_N IS NULL;
Как вычесть из даты дни sql
Нужно в запросе, в вычисляемом поле получить дату, есть дата входящего документа»ДатаВходящая» есть количество дней отсрочки платежа»СрокОплаты» , функция ДобавитьКДате(ДатаВходящая,»День»,СрокОплаты) всем хороша, но вот если нужно отнять количество дней, а дни в поле хранятся как положительное значение, хранить как отрицательное нет желание.
нужно получить вывитание в конструкции выбор
ВЫБОР
КОГДА СРОКОПЛАТЫ1 > СРОКОПЛАТЫ2
ТОГДА ДатаВходящая-СРОКОПЛАТЫ1
ИНАЧЕ ДатаВходящая-СРОКОПЛАТЫ2
КОНЕЦ
а на банальное вычитаие само собой ругаеться
ДобавитьКДате(ДатаВходящая,»День», — СрокОплаты)
?
ДОБАВИТЬКДАТЕ
РАЗНОСТЬДАТ
тут вопрос я могу использовать эти конструкции в тексте запроса а не в СКД ?
(2) Что не так?
а где собственно посмотреть синтаксис к операторам? СП нету
(6) ругаеться на неправильные параметры, причем в вычисляемых полях в СКД работает, а вот в конструкторе запроса ругается, что я делаю не так?
(7) погугли
а так, если попробуешь те операторы, которые в (3) все пойдет
2(7) потому что синтаксис языка запроса описан в кнопке по Ф1 а не в СП
(4) В тексте запроса без кавычек.
(7) Справка
-Содержание справки
-1С Предприятие
-Встроенный язык
-Работа с запросами
да спасибо за разъяснение, справка как всегда спасла, только это было собственоо только начало,
ВЫБОР
КОГДА ГрафикОплат.СрокОплаты1 > ГрафикОплат.СрокОплаты2
ТОГДА ДОБАВИТЬКДАТЕ(ПоступлениеТоваровУслуг.ДатаВходящегоДокумента, ДЕНЬ, -ГрафикОплат.СрокОплаты1)
ИНАЧЕ ДОБАВИТЬКДАТЕ(ПоступлениеТоваровУслуг.ДатаВходящегоДокумента, ДЕНЬ, -ГрафикОплат.СрокОплаты2)
КОНЕЦ КАК МаксимальныйСрок
Вот такая конструкция сделает вычисляемое поле с псевдонимом МаксимальныйСрок, а можно ли включитать такие поля в условие
ГДЕ
МаксимальныйСрок МЕЖДУ &НачалоПериода И &КонецПериода
у меня ругаеться что поле не найденно
ГДЕ
ВЫБОР
КОГДА ГрафикОплат.СрокОплаты1 > ГрафикОплат.СрокОплаты2
ТОГДА ДОБАВИТЬКДАТЕ(ПоступлениеТоваровУслуг.ДатаВходящегоДокумента, ДЕНЬ, -ГрафикОплат.СрокОплаты1)
ИНАЧЕ ДОБАВИТЬКДАТЕ(ПоступлениеТоваровУслуг.ДатаВходящегоДокумента, ДЕНЬ, -ГрафикОплат.СрокОплаты2)
КОНЕЦ МЕЖДУ &НачалоПериода И &КонецПериода
ввооот даже как. и тогда в выборку попадут данные ограниченные параметрами.
ааа туплю туплю сорри
ГДЕ
ДОБАВИТЬКДАТЕ(ПоступлениеТоваровУслуг.ДатаВходящегоДокумента, ДЕНЬ, -(ВЫБОР
КОГДА ГрафикОплат.СрокОплаты1 > ГрафикОплат.СрокОплаты2
ТОГДА ГрафикОплат.СрокОплаты1
ИНАЧЕ ГрафикОплат.СрокОплаты2
КОНЕЦ)) МЕЖДУ &НачалоПериода И &КонецПериода
Блин конструктор принимает, а при выполнении валиться с ошибкой, даже если я выбираю значения параметров, такие если из них вычесть сроки небудет меньше нулевого года. а так
Ошибка при исполнении запроса набора данных
по причине:
Ошибка выполнения запроса «Ошибка при выполнении операции над данными:
Microsoft OLE DB Provider for SQL Server: Добавление значения в столбец «datetime» привело к переполнению.
HRESULT=80040E07, SQLSrvr: Error state=1, Severity=10, native=517, line=1
»
по причине:
Ошибка при выполнении операции над данными:
Microsoft OLE DB Provider for SQL Server: Добавление значения в столбец «datetime» привело к переполнению.
HRESULT=80040E07, SQLSrvr: Error state=1, Severity=10, native=517, line=1
да есть только что поставил на проверку
так что если они есть то теперь 0 а все равно валится
(18) >даже если я выбираю значения параметров, такие если из них вычесть сроки небудет меньше нулевого года
Вычитается не из параметров, а из ПоступлениеТоваровУслуг.ДатаВходящегоДокумента.
Так вот, а если там незаполено? Или много вычитается?
(22)* незаполнено
ну максимум 90 дней вычитается, это можно проверить, может 0 вычитаться(полученный в результате ЕСТЬNULL) может -1, а ПоступлениеТоваровУслуг.ДатаВходящегоДокумента тоже проверяеться на NULL если не заполненно то ПоступлениеТоваровУслуг.Дата
ВЫБРАТЬ
ПоступлениеТоваровУслуг.Ссылка,
ПоступлениеТоваровУслуг.Дата,
ВЫБОР
КОГДА ПоступлениеТоваровУслуг.ДатаВходящегоДокумента ЕСТЬ NULL
ТОГДА ПоступлениеТоваровУслуг.Дата
ИНАЧЕ ПоступлениеТоваровУслуг.ДатаВходящегоДокумента
КОНЕЦ КАК ДатаВходящегоДокумента,
ПоступлениеТоваровУслуг.ДоговорКонтрагента,
ПоступлениеТоваровУслуг.СуммаДокумента,
ЕСТЬNULL(ГрафикОплат.СрокОплаты1, 0) КАК СрокОплаты1,
ГрафикОплат.ЧастьОплаты1,
ЕСТЬNULL(ГрафикОплат.СрокОплаты2, 0) КАК СрокОплаты2,
ГрафикОплат.ЧастьОплаты2,
ПоступлениеТоваровУслуг.Контрагент
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГрафикОплат КАК ГрафикОплат
ПО ПоступлениеТоваровУслуг.Контрагент = ГрафикОплат.Поставщик
ГДЕ
ГрафикОплат.Договор = &ПустаяСсылка
И ДОБАВИТЬКДАТЕ(ПоступлениеТоваровУслуг.ДатаВходящегоДокумента, ДЕНЬ, -ВЫБОР
КОГДА ГрафикОплат.СрокОплаты1 > ГрафикОплат.СрокОплаты2
ТОГДА ГрафикОплат.СрокОплаты1
ИНАЧЕ ГрафикОплат.СрокОплаты2
КОНЕЦ) МЕЖДУ &НачалоПериода И &КонецПериода
ВЫБРАТЬ
ПоступлениеТоваровУслуг.Ссылка,
ПоступлениеТоваровУслуг.Дата,
ВЫБОР
КОГДА ПоступлениеТоваровУслуг.ДатаВходящегоДокумента ЕСТЬ NULL
ТОГДА ПоступлениеТоваровУслуг.Дата
ИНАЧЕ ПоступлениеТоваровУслуг.ДатаВходящегоДокумента
КОНЕЦ,
ПоступлениеТоваровУслуг.ДоговорКонтрагента,
ПоступлениеТоваровУслуг.СуммаДокумента,
ЕСТЬNULL(ГрафикОплат.СрокОплаты1, 0),
ГрафикОплат.ЧастьОплаты1,
ЕСТЬNULL(ГрафикОплат.СрокОплаты2, 0),
ГрафикОплат.ЧастьОплаты2,
ПоступлениеТоваровУслуг.Контрагент
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГрафикОплат КАК ГрафикОплат
ПО ПоступлениеТоваровУслуг.Контрагент = ГрафикОплат.Поставщик
И ПоступлениеТоваровУслуг.ДоговорКонтрагента = ГрафикОплат.Договор
ГДЕ
ГрафикОплат.Договор = &ПустаяСсылка
И ДОБАВИТЬКДАТЕ(ПоступлениеТоваровУслуг.ДатаВходящегоДокумента, ДЕНЬ, -ВЫБОР
КОГДА ГрафикОплат.СрокОплаты1 > ГрафикОплат.СрокОплаты2
ТОГДА ГрафикОплат.СрокОплаты1
ИНАЧЕ ГрафикОплат.СрокОплаты2
КОНЕЦ) МЕЖДУ &НачалоПериода И &КонецПериода
(25) Ну и посмотри на свои ГДЕ. Из чего вычитаешь? И что вычитаешь?
И потом там(ПоступлениеТоваровУслуг.ДатаВходящегоДокумента) не NULL, а пустая дата может быть.
И вычитаешь возможно NULL-ы(ЕстьNull-ы и в ГДЕ надо прописать).
да согласен, пропустил невнимательно, а вот я могу псевдонимы испольтзовать что бы не писать ЕСТЬNULL везде?
(27) В ГДЕ псевдонимы не используются.
Собака все равно валиться .
ВЫБРАТЬ
ПоступлениеТоваровУслуг.Ссылка,
ПоступлениеТоваровУслуг.Дата,
ВЫБОР
КОГДА ПоступлениеТоваровУслуг.ДатаВходящегоДокумента ЕСТЬ NULL
ТОГДА ПоступлениеТоваровУслуг.Дата
ИНАЧЕ ПоступлениеТоваровУслуг.ДатаВходящегоДокумента
КОНЕЦ КАК ДатаВходящегоДокумента,
ПоступлениеТоваровУслуг.ДоговорКонтрагента,
ПоступлениеТоваровУслуг.СуммаДокумента,
ЕСТЬNULL(ГрафикОплат.СрокОплаты1, 0) КАК СрокОплаты1,
ГрафикОплат.ЧастьОплаты1,
ЕСТЬNULL(ГрафикОплат.СрокОплаты2, 0) КАК СрокОплаты2,
ГрафикОплат.ЧастьОплаты2,
ПоступлениеТоваровУслуг.Контрагент
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГрафикОплат КАК ГрафикОплат
ПО ПоступлениеТоваровУслуг.Контрагент = ГрафикОплат.Поставщик
ГДЕ
ГрафикОплат.Договор = &ПустаяСсылка
И ДОБАВИТЬКДАТЕ(ВЫБОР
КОГДА ПоступлениеТоваровУслуг.ДатаВходящегоДокумента ЕСТЬ NULL
ТОГДА ПоступлениеТоваровУслуг.Дата
ИНАЧЕ ПоступлениеТоваровУслуг.ДатаВходящегоДокумента
КОНЕЦ, ДЕНЬ, -ВЫБОР
КОГДА ЕСТЬNULL(ГрафикОплат.СрокОплаты1, 0) > ЕСТЬNULL(ГрафикОплат.СрокОплаты2, 0)
ТОГДА ЕСТЬNULL(ГрафикОплат.СрокОплаты1, 0)
ИНАЧЕ ЕСТЬNULL(ГрафикОплат.СрокОплаты2, 0)
КОНЕЦ) МЕЖДУ &НачалоПериода И &КонецПериода
ВЫБРАТЬ
ПоступлениеТоваровУслуг.Ссылка,
ПоступлениеТоваровУслуг.Дата,
ВЫБОР
КОГДА ПоступлениеТоваровУслуг.ДатаВходящегоДокумента ЕСТЬ NULL
ТОГДА ПоступлениеТоваровУслуг.Дата
ИНАЧЕ ПоступлениеТоваровУслуг.ДатаВходящегоДокумента
КОНЕЦ,
ПоступлениеТоваровУслуг.ДоговорКонтрагента,
ПоступлениеТоваровУслуг.СуммаДокумента,
ЕСТЬNULL(ГрафикОплат.СрокОплаты1, 0),
ГрафикОплат.ЧастьОплаты1,
ЕСТЬNULL(ГрафикОплат.СрокОплаты2, 0),
ГрафикОплат.ЧастьОплаты2,
ПоступлениеТоваровУслуг.Контрагент
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГрафикОплат КАК ГрафикОплат
ПО ПоступлениеТоваровУслуг.Контрагент = ГрафикОплат.Поставщик
И ПоступлениеТоваровУслуг.ДоговорКонтрагента = ГрафикОплат.Договор
ГДЕ
ГрафикОплат.Договор = &ПустаяСсылка
И ДОБАВИТЬКДАТЕ(ВЫБОР
КОГДА ПоступлениеТоваровУслуг.ДатаВходящегоДокумента ЕСТЬ NULL
ТОГДА ПоступлениеТоваровУслуг.Дата
ИНАЧЕ ПоступлениеТоваровУслуг.ДатаВходящегоДокумента
КОНЕЦ, ДЕНЬ, -ВЫБОР
КОГДА ЕСТЬNULL(ГрафикОплат.СрокОплаты1, 0) > ЕСТЬNULL(ГрафикОплат.СрокОплаты2, 0)
ТОГДА ЕСТЬNULL(ГрафикОплат.СрокОплаты1, 0)
ИНАЧЕ ЕСТЬNULL(ГрафикОплат.СрокОплаты2, 0)
КОНЕЦ) МЕЖДУ &НачалоПериода И &КонецПериода
Ну в не NULL тут:
КОГДА ПоступлениеТоваровУслуг.ДатаВходящегоДокумента ЕСТЬ NULL
Попробуй:
КОГДА ПоступлениеТоваровУслуг.ДатаВходящегоДокумента = ДатаВремя(1,1,1)
Руководство по SQL. Функции даты.
Ниже приведён список важных функций, которые относятся к дате и времени. Все данные функции доступны для работы с помощью SQL.
Примеры, приведённые ниже предназначены для RDBMS MySQL.
| Name | Description |
|---|---|
| ADDDATE() | Добавляет дату |
| ADDTIME() | Добавляет время |
| CONVERT_TZ() | Конвертирует одну временную зону в другую. |
| CURDATE() | Возвращает текущую дату. |
| CURRENT_DATE(), CURRENT_DATE | То же самое, что и CURDATE. |
| CURTIME() | Возвращает текущее время |
| NOW() | Возвращает текущие дату и время. |
| CURRENT_TIME(), CURRENT_TIME | То же самое, что и NOW() |
| DATE_ADD() | Добавляет две даты |
| DATE_FORMAT() | Определяет формат даты |
| DATE_SUB() | Разбивает две даты |
| DATE() | Возвращает только дату (число, месяц, год) из даты. |
| DATEDIFF() | Разделяет две даты |
| DAY() | То же самое, что и DAYOFMONTH() |
| DAYNAME() | Возвращает имя дня недели. |
| DAYOFMONTH() | Возвращает день месяца |
| DAYOFWEEK() | Возвращает индекс аргумента дня недели |
| DAYOFYEAR() | Возвращает номер дня в году (1 – 366) |
| EXTRACT | Выдаёт часть даты |
| FROM_DAYS() | Конвертирует номер дня в дату. |
| FROM_UNIXTIME() | Форматирует дату в дата/время для UNIX систем. |
| HOUR() | Возвращает часы |
| LAST_DAY | Возвращает крайний день месяца. |
| LOCALTIME(), LOCALTIME | То же самое, что и NOW() |
| LOCALTIMESTAMP, LOCALTIMESTAMP() | То же самое, что и NOW() |
| MAKEDATE() | Создаёт дату из года и дня в году |
| MAKETIME | Создаёт время |
| MICROSECOND() | Возвращает микросекунды |
| MINUTE() | Возвращает только минуты |
| MONTH() | Возвращает только месяц |
| MONTHNAME() | Возвращает имя месяца |
| CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP | Синоним для NOW() |
| PERIOD_ADD() | Добавляет период для в месяце-году. |
| PERIOD_DIFF() | Возвращает количество месяцев в периоде. |
| QUARTER() | Возвращает квартал |
| SEC_TO_TIME() | Конвертирует секунды в формат ‘ЧЧ:ММ:СС’ |
| SECOND() | Возвращает секунды (0 – 59) |
| STR_TO_DATE() | Конвертирует строку в дату |
| SUBDATE() | То же самое, что и DATE_SUB() Требует три аргумента |
| SUBTIME() | Разделяет время |
| SYSDATE() | Возвращает системное время |
| TIME_FORMAT() | Определяет формат времени |
| TIME_TO_SEC() | Конвертирует время в секунды |
| TIME() | Возвращает время. |
| TIMEDIFF() | Отделяет время |
| TIMESTAMP() | Возвращает текущие дату и время. |
| TIMESTAMPADD() | Добавляет период дата/время |
| IMESTAMPDIFF() | Отделяет интервал из дата/время |
| TO_DAYS() | Конвертирует дату в дни |
| UNIX_TIMESTAMP() | Возвращает дату/время для UNIX систем |
| UTC_DATE() | Возвращает дату UTC |
| UTC_TIME() | Возвращает время UTC |
| UTC_TIMESTAMP() | Возвращает дату/время UTC |
| WEEK() | Возвращает номер недели |
| WEEKDAY() | Возвращает индекс дня недели |
| WEEKOFYEAR() | Возвращает номер недели в году (1 – 53) |
| YEAR() | Возвращает год |
| YEARWEEK() | Возвращает год и неделю |
Примеры
Добавление даты (ADDDATE)
mysql> SELECT DATE_ADD('2016-06-30', INTERVAL 30 DAY); +-----------------------------------------+ | DATE_ADD('2016-06-30', INTERVAL 30 DAY) | +-----------------------------------------+ | 2016-07-30 | +-----------------------------------------+ 1 row in set (0.00 sec)
Добавление времени (ADDTIME)
mysql> SELECT ADDTIME('2016-06-06 23:59:59', '2 2:2:2.0'); +---------------------------------------------+ | ADDTIME('2016-06-06 23:59:59', '2 2:2:2.0') | +---------------------------------------------+ | 2016-06-09 02:02:01 | +---------------------------------------------+ 1 row in set (0.00 sec)
Конвертация временной зоны (CONVERT_TZ)
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+03:00'); +-----------------------------------------------------+ | CONVERT_TZ('2004-01-01 12:00:00','+00:00','+03:00') | +-----------------------------------------------------+ | 2004-01-01 15:00:00 | +-----------------------------------------------------+ 1 row in set (0.00 sec)
Текущая дата (CURDATE())
mysql> SELECT CURDATE(); +------------+ | CURDATE() | +------------+ | 2016-06-04 | +------------+ 1 row in set (0.00 sec)
Текущее время (CURTIME())
mysql> SELECT CURTIME(); +-----------+ | CURTIME() | +-----------+ | 14:19:55 | +-----------+ 1 row in set (0.00 sec)
Дата (DATE)
mysql> SELECT DATE('2016-06-04 15:00:00'); +-----------------------------+ | DATE('2016-06-04 15:00:00') | +-----------------------------+ | 2016-06-04 | +-----------------------------+ 1 row in set (0.00 sec)
Разница во времени (DATEDIFF())
mysql> SELECT DATEDIFF ('2016-06-06 00:00:00', '1988-10-28 12:00:00'); +---------------------------------------------------------+ | DATEDIFF ('2016-06-06 00:00:00', '1988-10-28 12:00:00') | +---------------------------------------------------------+ | 10083 | +---------------------------------------------------------+ 1 row in set (0.00 sec)
Добавление даты (DATEADD(), DATE_SUB())
Данные функции обеспечивают арифметику дат. Мы можем добавить или отнять определённый интервал времени от определённой даты.
Ниже приведена таблица, в которой указаны возможные аргументы для интервалов:
| Значение | Ожидаемый формат |
| MICROSECOND | Микросекунды |
| SECOND | Секунды |
| MINUTE | Минуты |
| HOUR | Часы |
| DAY | Дни |
| WEEK | Недели |
| MONTH | Месяцы |
| QUARTER | Кварталы |
| YEAR | Годы |
| SECOND_MICROSECOND | ‘Секунды.Микросекунды’ |
| MINUTE_MICROSECOND | Минуты.Микросекунды’ |
| MINUTE_SECOND | ‘Минуты.Секунды’ |
| HOUR_MICROSECOND | ‘Часы.Микросекунды’ |
| HOUR_SECOND | ‘Часы.Секунды.Микросекунды’ |
| HOUR_MINUTE | ‘Часы.Минуты’ |
| DAY_MICROSECOND | ‘Дни.Микросекунды’ |
| DAY_SECOND | Дни.Часы.Минуты.Секунды |
| DAY_MINUTE | Дни.Часы.Минуты |
| DAY_HOUR | Дни.Часы |
| YEAR_MONTH | Года.Месяцы |
mysql> SELECT DATE_ADD('2016-06-04 20:00:00', INTERVAL '1:1' DAY_HOUR); +----------------------------------------------------------+ | DATE_ADD('2016-06-04 20:00:00', INTERVAL '1:1' DAY_HOUR) | +----------------------------------------------------------+ | 2016-06-05 21:00:00 | +----------------------------------------------------------+ 1 row in set (0.00 sec)
Формат даты
Формат даты определяется с помощью специальных символов.
Список таких символов приведён в таблице, которая находится ниже:
| Спецификатор | Описание |
| %a | Сокращённое имя дня недели |
| %b | Сокращённое имя месяца |
| %c | Номер месяца |
| %D | День месяца с английским суффиксом |
| %d | Номер дня в месяце (00 … 31) |
| %e | Номер дня в месяце (0 … 31) |
| %f | Микросекунды (000000 … 999999) |
| %H | Часы (00 … 23) |
| %h | Часы (01 … 12) |
| %I | Часы (01 … 12) |
| %i | Минуты (00 … 59) |
| %j | Дни года (001 … 366) |
| %k | Часы (00 … 23) |
| %l | Часы (1 … 12) |
| %M | Имя месяца |
| %m | Номер месяца |
| %p | AM или PM |
| %r | Время с использованием AM или PM |
| %S | Секунды (00 … 59) |
| %s | Секунды (00 … 59) |
| %T | Время (ЧЧ:ММ:СС) |
| %U | Неделя (00 … 53). Первый день недели – Воскресенье |
| %u | Неделя (00 … 53). Первый день недели – Понедельник |
| %V | Неделя (00 … 53). Первый день недели – Воскресенье. Используется с %X |
| %v | Неделя (00 … 53). Первый день недели – Понедельник. Используется с %x |
| %W | День недели |
| %w | День недели (0 – Воскресенье … 6 – Суббота) |
| %X | Год для недели. Воскресенье – первый день недели. Используется с %V |
| %x | Год для недели. Понедельник – первый день недели. Используется с %v |
| %Y | Год (YYYY) |
| %y | Год (YY) |
| %% | Символ .%. |
| %x | То же самое для любых элементов, указанных выше |
mysql> SELECT DATE_FORMAT ('2016-06-04 22:00:00', '%W %M %Y'); +-------------------------------------------------+ | DATE_FORMAT ('2016-06-04 22:00:00', '%W %M %Y') | +-------------------------------------------------+ | Saturday June 2016 | +-------------------------------------------------+ 1 row in set (0.00 sec)
Имя дня (DAYNAME())
mysql> SELECT DAYNAME('1988-10-28'); +-----------------------+ | DAYNAME('1988-10-28') | +-----------------------+ | Friday | +-----------------------+ 1 row in set (0.00 sec)
День месяца (DAYOFMONTH())
mysql> SELECT DAYOFMONTH('1988-10-28'); +--------------------------+ | DAYOFMONTH('1988-10-28') | +--------------------------+ | 28 | +--------------------------+ 1 row in set (0.01 sec)
День недели (DAYOFWEEK())
mysql> SELECT DAYOFWEEK('1988-10-28'); +-------------------------+ | DAYOFWEEK('1988-10-28') | +-------------------------+ | 6 | +-------------------------+ 1 row in set (0.00 sec)
День в году (DAYOFYEAR())
mysql> SELECT DAYOFYEAR('1988-10-28'); +-------------------------+ | DAYOFYEAR('1988-10-28') | +-------------------------+ | 302 | +-------------------------+ 1 row in set (0.00 sec)
Неделя (WEEK())
mysql> SELECT WEEK('1988-10-28'); +--------------------+ | WEEK('1988-10-28') | +--------------------+ | 43 | +--------------------+ 1 row in set (0.00 sec)
На этом мы заканчиваем изучение функций даты в языке SQL.
В следующей статье мы рассмотрим временные таблицы.
