powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / текущий год и месяц назад
22 сообщений из 22, страница 1 из 1
текущий год и месяц назад
    #40078196
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create table #tt (d datetime)
go
insert into #tt (d)
	select ('20201130') union all
	select ('20201201') union all
	select ('20201230') union all
	select ('20210101') union all 
	select ('20210105') union all 
	select (getdate())

select t.* from #tt t where t.d >= dateadd(month, -1, cast(convert(char(4), year(getdate()), 20) + '0101' as datetime)) --year(t.d) = year(getdate()) 

go
drop table #tt



Подскажите, пожалуйста, можно ли это было выполнить без convert'ов? Нужен текущий год (месяц, час...) и последний месяц (час, минута...) предыдущего. Спасибо.
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078210
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Julia2000,

вы очень неясно выражаетесь. Лучше приведите примеры того, что должно получиться.
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078213
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap
Julia2000,

вы очень неясно выражаетесь. Лучше приведите примеры того, что должно получиться.


Результат у меня получается правильный. Но, возможно, можно тоже самое сделать но без convert/cast, а с функциями даты/времени только?
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078218
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Julia2000,

Код: sql
1.
select t.* from #tt t where t.d >= dateadd(day, 1, eomonth(dateadd(month, -month(getdate()), getdate()), -1))
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078227
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов
Julia2000,

Код: sql
1.
select t.* from #tt t where t.d >= dateadd(day, 1, eomonth(dateadd(month, -month(getdate()), getdate()), -1))



Спасибо. К сожалению версия сервера старая. Простите, забыла написать. MS SQL 2008 R2
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078312
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Честно не знаю какой вариант лучше. Первый с преобразованием в текст и обратно или этот. Лучше в смысле оптимальнее по производительности, когда запросов в определенный период могут быть тысячи.
Для случая, когда нужно выбрать текущий год и последний месяц предыдущего года. Также бывают и иные вариации, вроде текущий месяц и последний час предыдущего месяца, но решение уже по имеющемуся шаблону...)

Код: sql
1.
2.
3.
declare @d datetime set @d= getdate()
set @d = dateadd(day, datediff(day, 0, @d), 0)
select dateadd(day, -day(dateadd(month, -month(@d), @d)) + 1, dateadd(month, -month(@d), @d)) as res
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078373
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Julia2000,

Что Вам мешает сохранить последний месяц года в таблице? Запишите последние месяцы года на сто лет вперёд и не терзайтесь сомнениями.
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078467
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов,
Извините, но не совсем подходит. Во-первых, происходит изменение данных и в таком случае понадобится синхронизировать, во-вторых, как я написала выше, это только один из случаев, когда данные за текущий год плюс последний месяц прошлого, а там есть еще и куча вариаций с таким же смыслом, например, за текущий месяц и последний день предыдущего и так далее, в итоге 1000 дополнительных таблиц, которые еще и синхронизировать... :\
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078476
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[removed]
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078478
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А почему просто не вычесть из даты 13 месяцев?
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078490
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SQL2008
А почему просто не вычесть из даты 13 месяцев?


Потому, что сегодня 18 июня и мне нужен период с 2020-12-01 0:00 по сейчас, а не минус 13 месяцев. )
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078536
Wlr-l
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если от текущей даты отнять деньГода, то получим последний день последнего месяца предыдущего года.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with A(d) as (
  select '20201130' union all
  select '20201201' union all
  select '20201230' union all
  select '20210101' union all 
  select '20210105'
)
select d, dateadd(day, -datepart(dayofyear, d),    d) as m12last
        , dateadd(day, -datepart(dayofyear, d)-30, d) as m12first
  from A;



Код: plaintext
1.
2.
3.
4.
5.
6.
d       	m12last 	m12first
20201130	2019-12-31	2019-12-01
20201201	2019-12-31	2019-12-01
20201230	2019-12-31	2019-12-01
20210101	2020-12-31	2020-12-01
20210105	2020-12-31	2020-12-01
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078572
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Wlr-l,

Спасибо! Почему-то меня сначала смутило dateadd(day, -datepart(dayofyear, d) -30 , d) as m12first, но все правильно работает!
Хотя и не идеально хороший вариант, исходя из всех моих запросов, но уже значительно проще.
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078651
Wlr-l
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Арифметика дат и арифметика времени существенно сложнее арифметики целых чисел и это от нас не зависит.

Что касается 30-ти. Последний день последнего месяца (это декабрь) предыдущего года находится сравнительно просто: он отстоит от текущей даты на dayofyear дней. В декабре всегда 31 день и в обозримом будущем это не изменится. Следовательно, первый день декабря предыдущего года будет отстоять от текущей даты на dayofyear+30 дней в глубь веков (31-30=1).
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078819
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Julia2000
Потому, что сегодня 18 июня и мне нужен период с 2020-12-01 0:00 по сейчас, а не минус 13 месяцев. )


"текущий год и месяц назад" - я понял как один год и месяц назад, т.е. 12 + 1 месяц назад.

а подразумевалось, что "первый день последнего месяца прошлого года"?

почему нельзя было сформулировать задачу по-русски?
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078822
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Wlr-l
Арифметика дат и арифметика времени существенно сложнее арифметики целых чисел и это от нас не зависит.

Что касается 30-ти. Последний день последнего месяца (это декабрь) предыдущего года находится сравнительно просто: он отстоит от текущей даты на dayofyear дней. В декабре всегда 31 день и в обозримом будущем это не изменится. Следовательно, первый день декабря предыдущего года будет отстоять от текущей даты на dayofyear+30 дней в глубь веков (31-30=1).


А также я сомневалась за февраль, но оказалось все правильно работает. Спасибо!
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078864
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
Julia2000
Потому, что сегодня 18 июня и мне нужен период с 2020-12-01 0:00 по сейчас, а не минус 13 месяцев. )


"текущий год и месяц назад" - я понял как один год и месяц назад, т.е. 12 + 1 месяц назад.

а подразумевалось, что "первый день последнего месяца прошлого года"?

почему нельзя было сформулировать задачу по-русски?
Такие вопросы она игнорирует 22336584
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40078913
Julia2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap
SQL2008
пропущено...


"текущий год и месяц назад" - я понял как один год и месяц назад, т.е. 12 + 1 месяц назад.

а подразумевалось, что "первый день последнего месяца прошлого года"?

почему нельзя было сформулировать задачу по-русски?
Такие вопросы она игнорирует 22336584


Нужен текущий год (месяц, час...) и последний месяц (час, минута...) предыдущего .

Извините, но это было в самом первом топике...

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

Но, тему можно закрыть, задача в общем-то решена. Если не будет иных супер-пупер-офигенных-грамотных предложений. )))
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40079017
Фотография SIMPLicity_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2008R2:

Код: sql
1.
2.
select @@VERSION
select getdate(), year(getdate()) as [год], month(getdate()) [месяц], day(getdate()) [число], cast(getdate() as date) [чисто Дата], cast(getdate() as time) [чисто Время]


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2008 (SP2) - 10.0.4316.0 (X64) 
	Jul  5 2011 16:02:15 
	Copyright (c) 1988-2008 Microsoft Corporation
	Standard Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)


(затронута одна строка)

                        год         месяц       число       чисто Дата чисто Время
----------------------- ----------- ----------- ----------- ---------- ----------------
2021-06-20 20:04:26.283 2021        6           20          2021-06-20 20:04:26.2830000

(затронута одна строка)
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40079020
Фотография SIMPLicity_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Julia2000
Здравствуйте.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create table #tt (d datetime)
go
insert into #tt (d)
	select ('20201130') union all
	select ('20201201') union all
	select ('20201230') union all
	select ('20210101') union all 
	select ('20210105') union all 
	select (getdate())

select t.* from #tt t where t.d >= dateadd(month, -1, cast(convert(char(4), year(getdate()), 20) + '0101' as datetime)) --year(t.d) = year(getdate()) 

go
drop table #tt


Подскажите, пожалуйста, можно ли это было выполнить без convert'ов? Нужен текущий год (месяц, час...) и последний месяц (час, минута...) предыдущего. Спасибо.

тоже норм вариант. Так делал.

Ну если надо вот-вот-вот всё до самой последней миллисекунды, то используйте строгое неравенство с началом следующего дня: то есть < '20210101' - можно и без времени - тогда всё вплоть до 20201231T23:59:59.99999 попадёт в отбор. Если я правильно понял Вашу задачу...
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40079699
Wlr-l
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
" тоже норм вариант. Так делал. "

И я так делал, когда у нас появился SQL Server 7. С тех пор остался один конвертор данных одного типа приборов, который сравнивает даты путем их преобразования в строки. Он уже два десятка лет трудится безотказно, днем и ночью, утром и вечером, хотя сервер уже далеко не 7-ка и за это время сменилось не одно поколение приборов и конверторов их данных. Несмотря на это я не рекомендую этот способ, так как есть тип данных "дата" и в нем достаточно операций, чтобы получить любой результат.

Секрет работы с датами прост. Да, в разных месяцах может быть разное число дней и даже бывают високосные годы. Но, если выбрать точку отсчета и перенумеровать последующие даты, то получим монотонную строго возрастающую последовательность. Главное уметь находить характерные (опорные) точки в этой последовательности дат. Такими точками могут быть начало года, квартала, месяца, недели. И уже от этих опорных точек искать расстояние до нужной даты в годах, кварталах, месяцах, неделях, днях.

Я привел общеизвестный способ нахождения опорной точки, используя порядковый номер даты в пределах одного года. Можно пойти по другому пути. Найти начало года, а от него уже искать начало последнего месяца предыдущего года.

Для поиска начала года нужно выбрать опорную дату. Выбор дня и месяца этой даты невелик: это 1-й день 1-го месяца года. Год можно выбрать от 1753 до 9999. Очень часто опорную дату задают нулем (0). Я считаю, что это хотя и короче, но снижается наглядность, так как 0 ассоциируется с числом, а не с датой.

Теперь, если от года текущей даты отнять год опорной даты и полученную разность прибавить (разумеется, в годах) к опорной дате, то мы получим начало года, к которому относится текущая дата. Если от полученной даты отнять 31 день, то получим начало последнего года предыдущего месяца.

Наконец-то, в новых версиях SQL сервера добавлены функции формирования дат со временем или без него из составных частей, например, datefromparts.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with A(d) as (
  select '20201130' union all
  select '20201201' union all
  select '20201230' union all
  select '20210101' union all 
  select '20210105'
)
select d, dateadd(day, -datepart(dayofyear, d),    d) as m12last
        , dateadd(day, -datepart(dayofyear, d)-30, d) as m12first
        , dateadd(day, -31, dateadd(year, Year(d)-Year(0), 0))
        , dateadd(day, -31, dateadd(year, Year(d)-Year('19000101'), '19000101'))
        , dateadd(day, -31, dateadd(year, Year(d)-Year('29000101'), '29000101'))
        , dateadd(day, -31, dateadd(year, Year(d)-Year('17530101'), '17530101'))
        , dateadd(day, -31, dateadd(year, datediff(year, '17530101', d), '17530101'))
        , datefromparts(Year(d)-1, 12, 01)
  from A;


И если формировать дату из строки, то выражение
Код: sql
1.
dateadd(month, -1, cast(convert(char(4), year(d), 20) + '0101' as datetime))


можно упростить:
Код: sql
1.
cast(str(Year(d)-1) + '1201' as datetime)
...
Рейтинг: 0 / 0
текущий год и месяц назад
    #40079713
Wlr-l
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Осталось рассмотреть предложение Владислава Колосова: рассчитать заранее нужные даты и хранить их в таблице, не терзаясь сомнениями.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with – Таблица-календарь
 l0(n) as (select 0 union all select 0 union all select 0 union all select 0 union all select 0 union all select 0 union all select 0 union all select 0), 
 l1(n) as (select 0 from l0 t1 cross join l0 t2),
 l2(n) as (select 0 from l1 t1 cross join l1 t2),
 r(n)  as (select row_number() over(order by (select 0)) from l2),
 d     as (select n
                 ,dateadd(day, n, '20190101') as d
                 ,dateadd(day, -datepart(dayofyear, dateadd(day, n, '20190101')),    dateadd(day, n, '20190101')) as m12last
                 ,dateadd(day, -datepart(dayofyear, dateadd(day, n, '20190101'))-30, dateadd(day, n, '20190101')) as m12first
             from r)
 -- select * from d;

, A(d) as (  -- ваша таблица
  select '20201130' union all
  select '20201201' union all
  select '20201230' union all
  select '20210101' union all 
  select '20210105'
)

select a.d, d.m12first, d.m12last
  from A a
  join d d on a.d=d.d;


Данная таблица-календарь хранит для каждой даты из выбранного диапазона дат начало и конец последнего месяца предыдущего года. В данном случае хранится 4 тыс. дат, начиная с 2019 года, что должно хватить на 10 лет. Эта таблица рассчитывается один раз. Ничто не мешает добавить в нее столбцы с другими нужными данными и использовать их в других запросах. Также ничто не мешает сделать несколько разных таблиц-календарей.

Конечно, начало и конец последнего месяца предыдущего года НЕ нужно хранить в рабочих таблицах.

Таблицы, аналогичные календарю, я вынес в отдельную базу данных DIR и эта база данных эпизодически обновляется, не затрагивая основные базы данных. А вот некоторые процедуры расчета после таких обновлений существенно упрощаются. Эти таблицы не нужно ни с чем синхронизировать и какая разница для рабочих баз данных, сколько таблиц находится в БД DIR, одна или тысяча?

Выбор расчета или таблицы-календаря регулируется "золотым правилом механики".
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / текущий год и месяц назад
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]