Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Отобрать записи в юбилей  [new]
~~~
Guest
коллеги, как лучше решить задачу:

есть таблица, в таблице некие даты (например дни рождения).

Например:

2000-01-01
2004-01-09
2005-01-02

Есть некие настройки, которые должны пометить запись у которой юбилей - например за 2 дня до юбилея и за 2 дня после.
Например отобрать записи с 30 декабря по 02 января независимо от года.

Как решить задачу без преобразования данных из таблицы?
21 сен 16, 12:33    [19691412]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
~~~
Guest
Т.е. задача - сравнить данные в таблице только по месяцу и дню, год игнорируется.
Как решить без преобразования данных в таблице?
21 сен 16, 12:36    [19691436]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
~~~,
за 2 дня до/после
DECLARE @BirthDay Date = '23 sep 2016'
IF ABS(DATEDIFF(day,@BirthDay,GETDATE())) <= 2
	SELECT @BirthDay 
21 сен 16, 12:38    [19691450]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
др в текущем году
DATEADD(YY, DATEPART(YYYY, GETDATE()) - DATEPART(YYYY,@BirthDay),@BirthDay)

если хотите просто число месяц то DATEPART() но без заморочек проще получить текущий/будущий и работать с ней
21 сен 16, 12:44    [19691504]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
~~~
Guest
TaPaK,

мне не нужно в текщем году.

Я наверное не очень хорошо описал задачу. Попробую еще раз.

Есть таблица с днями рождения (все роделись не в один год, а в разные):
declare @t table(dt date)

insert into @t(dt)
select '2000-09-21'
union all select '2004-09-30'
union all select '2005-09-22'



Есть текущая дата (21-09), нужно получить из этой таблицы все записи, дни рождения которых соответствуют текущей дате +- 2 дня.

Т.е. получить все даты между:
declare @day_before int = -2
		,@day_after int = 2
		,@cur_date date = getdate()

select '>= ' + right(cast(dateadd(day, @day_before, @cur_date) as varchar), 5) as [Date_before] 
,'<= ' + right(cast(dateadd(day, @day_after, @cur_date) as varchar), 5) as [Date_after]
		



Как решить, не преобразовывая даты в таблице (таблица большая)?
21 сен 16, 12:47    [19691533]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
~~~,

я как то не так написал?
21 сен 16, 12:49    [19691541]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
~~~,

вы можете к дате в таблице прибавить DATEDIFF(YEAR,Birthday,CURRENT_TIMESTAMP) лет
и накладывать ограничения не на поле таблицы, а на результат этой функции?
Про индексы и всякую такую же фигню надо будет, конечно, забыть. Но это издержки такие..
21 сен 16, 12:56    [19691626]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
~~~
Guest
TaPaK,

Ваш запрос формально решает задачу:

DECLARE @BirthDay Date = '23 sep 2016'
IF ABS(DATEDIFF(day,@BirthDay,GETDATE())) <= 2
	SELECT @BirthDay 


Но он преобразует колонку birthday. Я не могу так написать запрос - со сканом кластерного индекса, мне же это в where надо написать как условие.
Есть другие варианты?
21 сен 16, 12:56    [19691633]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
~~~
Guest
iap
~~~,
Про индексы и всякую такую же фигню надо будет, конечно, забыть. Но это издержки такие..


Вот как-то не очень хочется про них забывать. Не уже ли нет решения?
21 сен 16, 12:57    [19691648]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
~~~,
что бы остались индексы преобразовывайте текущую к дате рождения, тогда сравнение будет birthday BETWEEN a AND b но врядли вы получите seek в любом случае
21 сен 16, 13:03    [19691700]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
и для понимания, у вас там даты рождения всех людей планеты?
21 сен 16, 13:05    [19691723]     Ответить | Цитировать Сообщить модератору
 Re: Отобрать записи в юбилей  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Чтобы использовать индексы, надо привести таблицу к нормальной форме,
то есть, чтобы каждая колонка содержала одну неделимую сущность.
В данном случае - Месяц+День. Добавьте такое поле, и вам полегчает!
Оно, кстати, может быть и вычисляемым из поля с полной датой. По нему сделать индекс - и вуаля!
21 сен 16, 13:17    [19691846]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить