Начало и конец месяца
При работе с датами периодически приходится определять первый и последний день месяца по дате. Этим мы сейчас и займемся.
Для усечения даты в PostgreSQL есть функция date_trunc(поле, значение) . Работает она аналогично функции trunc для чисел.
SELECT date_trunc('day', timestamp '2023-02-17 13:25')
| # | date_trunc |
|---|---|
| 1 | 2023-02-17 00:00:00 |
Первый параметр функции date_trunc может принимать значения:
- microseconds
- milliseconds
- second
- minute
- hour
- day
- week
- month
- quarter
- year
- decade
- century
- millennium
Первый день месяца
С помощью функции date_trunc мы можем легко определить первый день месяца:
SELECT date_trunc('month', timestamp '2023-02-17 13:25')
| # | date_trunc |
|---|---|
| 1 | 2023-02-01 00:00:00 |
При желании можно привести результат к дате:
SELECT date_trunc('month', timestamp '2023-02-17 13:25')::date
| # | date_trunc |
|---|---|
| 1 | 2023-02-01 |
Первый день месяца можно получить преобразовав исходную дату в строку с годом и месяцем, а затем сделать обратное преобразование в дату, добавив 1-е число.
SELECT (to_char(timestamp '2023-02-17 13:25', 'YYYY-MM') || '-01')::date
| # | date |
|---|---|
| 1 | 2023-02-01 |
Последний день месяца
С последним днем месяца дела обстоят немножко сложнее. В месяце может быть от 28 до 31 дней в зависимости от месяца и года. Просто так подставить число в строку не получится.
На помощь нам придет получение первого числа месяца и добавление интервала в один месяц.
SELECT date_trunc('month', timestamp '2023-02-17 13:25') + interval '1 month' AS result
| # | result |
|---|---|
| 1 | 2023-03-01 00:00:00 |
Так мы получаем первое число следующего месяца. Теперь нам достаточно отнять один день и мы получим последний день текущего месяца:
SELECT date_trunc('month', timestamp '2023-02-17 13:25') + interval '1 month -1 day' AS result
| # | result |
|---|---|
| 1 | 2023-02-28 00:00:00 |
Итоговый запрос для получения дат первого и последнего дней месяца:
SELECT date_trunc('month', timestamp '2023-02-17 13:25') AS start, date_trunc('month', timestamp '2023-02-17 13:25') + interval '1 month -1 day' AS end
| # | start | end |
|---|---|---|
| 1 | 2023-02-01 00:00:00 | 2023-02-28 00:00:00 |
Добавление месяцев
Стоит отметить, как работает добавление месяцев к дате.
Если в исходной дате день месяца с 1 по 28, то в результате будет этот же день месяца.
SELECT timestamp '2023-02-17 13:25' + interval '1 month'
| # | ?column? |
|---|---|
| 1 | 2023-03-17 13:25:00 |
Для дней с 29 по 31 может получиться так, что после добавления нужного количества месяцев этого же числа не будет в месяце результата. В этом случае будет взят последний день месяца.
Например, к 31 января добавляем 1 месяц. 31 февраля не существует, поэтому результатом будет последний день февраля — 28 февраля (или 29 для високосного года).
SELECT date '2023-01-31' + interval '1 month'
| # | ?column? |
|---|---|
| 1 | 2023-02-28 00:00:00 |
Для високосного года:
SELECT date '2024-01-31' + interval '1 month'
| # | ?column? |
|---|---|
| 1 | 2024-02-29 00:00:00 |
Определение начала и конца года
Аналогично определению первого и последнего дня месяца можно найти первый и последний день года по дате.
SELECT date_trunc('year', timestamp '2023-02-17 13:25') AS start, date_trunc('year', timestamp '2023-02-17 13:25') + interval '1 year -1 day' AS end
| # | start | end |
|---|---|---|
| 1 | 2023-01-01 00:00:00 | 2023-12-31 00:00:00 |
9.11 Динамическое построение интервала
9.13 EXTRACT — извлечение из даты части (год, месяц, день. )
Как получить первое число след месяца sql
Чтобы получить первое число следующего месяца в SQL, можно использовать функцию DATEADD() . Эта функция добавляет определенный интервал времени к указанной дате. В нашем случае мы добавляем один месяц к текущей дате, а затем устанавливаем день в 1:
SELECT DATEADD(month, 1, DATEADD(day, 1 - DAY(GETDATE()), GETDATE())) AS first_day_of_next_month;
Здесь мы используем функцию GETDATE() для получения текущей даты, а затем вычитаем текущее число месяца из этой даты и добавляем 1 день, чтобы получить дату первого дня текущего месяца. Затем мы используем функцию DATEADD() с параметром month для добавления одного месяца к этой дате, чтобы получить дату первого дня следующего месяца.
Результатом будет дата первого числа следующего месяца. Обратите внимание, что формат даты может отличаться в зависимости от используемой СУБД.
Функция EOMONTH
Как узнать последний день месяца по заданной дате, например, текущего месяца?
Текущую дату мы можем узнать, используя встроенную функцию current_timestamp:

Консоль
Выполнить
Чтобы узнать последний день предыдущего месяца, мы можем от текущей даты отнять номер текущего дня месяца, т.е. количество дней, прошедших от начала месяца:

Консоль
Выполнить
Тогда для текущего месяца нам потребуется предварительно добавить один месяц к текущей дате:

Консоль
Выполнить
Уберем, наконец, из полученного результата компоненту времени:

Консоль
Выполнить
В Cистема управления реляционными базами данных (СУБД), разработанная корпорацией Microsoft. Язык структурированных запросов) — универсальный компьютерный язык, применяемый для создания, модификации и управления данными в реляционных базах данных. SQL Server 2012 появилась функция EOMONTH , которая позволяет сделать то же самое без применения «процедурной» логики:

Консоль
Выполнить
Если вы получаете ошибку при выполнении последнего запроса, значит учебник еще не переехал на версию SQL Server, поддерживающую EOMONTH.
Ну, а для времени, когда я написал этот запрос, результаты, естественно, совпали:
Мы уже знаем, что функция EOMONTH имеет аргументом выражение типа даты. Кроме того, функция имеет также второй (необязательный) целочисленный аргумент, представляющий число месяцев, которые, при наличии, будут добавлены к дате, представленной первым аргументом. Например, следующий запрос даст нам последние дни предыдущего, текущего и следующего месяца для даты ‘2016-01-28’:

Консоль
Выполнить
Галактика в вопросах и ответах
Прямой sql. Вычислить даты начала и конца месяца
Программирование на Атлантисе (VIP, FCOM, ARD), FastReport
6 сообщений • Страница 1 из 1
mwoland
Прямой sql. Вычислить даты начала и конца месяца
Сообщение mwoland » 28 апр 2014, 19:12
Доброго времени суток. Имеется запрос на прямом sql следующего вида:
Sql select dsopr from katsopr
Необходимо получить даты начала и конца месяца от даты dsopr в формате атлантиса, т.е. в итоге должно получиться что-то вроде
Sql select dsopr, month_first_date(dsopr), month_last_date(dsopr) from katsopr
Даты нужно вычислять без использования своих процедур на бд. Платформа ms sql.
Кто-нибудь решал подобный вопрос?
Den Местный житель Сообщения: 1839 Зарегистрирован: 29 мар 2005, 17:49 Откуда: Ярославская область ОАО «Часовой завод Чайка» г. Углич Контактная информация:
Re: Прямой sql. Вычислить даты начала и конца месяца
Сообщение Den » 29 апр 2014, 06:08
ну как то извращенно можно как то так попробовать
sql select nrec ,dsopr ,cast('01'||'/'||case when MONTH(datetime(dsopr, 0))>=10 then '' else '0' end ||MONTH(datetime(dsopr, 0))||'/'||YEAR(datetime(dsopr, 0)) as string) as mesbeg ,cast(case when MONTH(datetime(dsopr, 0)) in (1,3,5,7,8,10,12) then '31' when MONTH(datetime(dsopr, 0)) in (4,6,9,11) then '30' else '28' // а тута еще высокосные могут быть ) end ||'/'||case when MONTH(datetime(dsopr, 0))>=10 then '' else '0' end ||MONTH(datetime(dsopr, 0))||'/'||YEAR(datetime(dsopr, 0)) as string) as mesend from katsopr where vidsopr=201 and dsopr>=#date(01,01,2014) ;
Zver Местный житель Сообщения: 204 Зарегистрирован: 13 ноя 2012, 12:47 Откуда: СПб Контактная информация:
Re: Прямой sql. Вычислить даты начала и конца месяца
Сообщение Zver » 29 апр 2014, 13:25
Недавно решал подобную проблему с использованием функций даты и времени для MS SQL.
Надо было получить первое число некоторого месяца.
идея сводится к использованию функции dateadd. Вот реализация, надеюсь пригодится.
Declare @ReportDate as date = GetDate();
Declare @SkladNelikvDate as integer = master.dbo.DateToGalDate( DATEADD(month, -3 , @ReportDate) );—Дата для неликвидов на складе
—Пелучаем дату первого числа для месяца по неликвидам
Declare @Nelik_Date as date = master.dbo.GalDateToDate(@SkladNelikvDate); — для простоты следующего выражения
declare @DateForSaldMoun as integer = master.dbo.DateToGalDate( dateadd( DAY, -datePart(day, @Nelik_Date) + 1, @Nelik_Date));
Программист-самоучка
mwoland
Re: Прямой sql. Вычислить даты начала и конца месяца
Сообщение mwoland » 29 апр 2014, 14:46
Спасибо за ответы. Но. При реализации предложенной den’ом мы получаем дату не в формате атлантис, а строку (ну и конкретное утяжеление запроса как для чтения так и для его выполнения). Реализация предложенная zver’ем через dateadd классическая и правильная, но требует объявления своей процедуры и соответствующего ее подключения к галке, тк dateadd не доступна в прямом sql галки. Видимо, без своей процедуры не получится.
Den Местный житель Сообщения: 1839 Зарегистрирован: 29 мар 2005, 17:49 Откуда: Ярославская область ОАО «Часовой завод Чайка» г. Углич Контактная информация:
Re: Прямой sql. Вычислить даты начала и конца месяца
Сообщение Den » 29 апр 2014, 15:10
«Даты нужно вычислять без использования своих процедур на бд» (с)
я думал Вам приницпиален по каким то причинам был этот момент- как входнео условие задачи. А так ,канешн, процедуру и все гуд будет
mwoland
Re: Прямой sql. Вычислить даты начала и конца месяца
Сообщение mwoland » 29 апр 2014, 16:39
Да, крайне не хотелось использовать процедуры. Спасибо, что попытались решить задачу без их использования.