Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Определить сегодня ли ДР по дате  [new]
new dev
Member

Откуда:
Сообщений: 36
Добрый день,

Есть поле дата рождения типа datetime и индекс по этому полю. Нужно выбрать из таблицы только те записи, у которых сегодня ДР. Использую datepart() в условии поиска, но запрос долго выполняется, поскольку индекс не используется. Можно ли тут исхитриться и написать условие, чтобы оптимизатор использовал индекс?
12 июл 09, 16:39    [7405945]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
aleks2
Guest
declare @dt datetime, @i int
declare @t table(dt datetime primary key clustered)

set @dt=datediff(day,0,getdate())
set @i=-100
while @i<=0 begin
  insert @t values(DATEADD(year,@i,@dt))
  set @i=@i+1
end

select T.*
from aTable T inner join @t X
ON X.dt=T.[день рождения]


Человек так недолговечен...
12 июл 09, 16:57    [7405964]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36800
Вряд ли. Я бы сделал для этих целей два поля - день и месяц рождения, с индексом по нему.
12 июл 09, 16:57    [7405965]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Можно сделать вычисляемое поле и индекс по нему
BirthDate AS RIGHT(CONVERT(VARCHAR(8),BirthDay,112),4))
12 июл 09, 19:44    [7406112]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Alex_Toms
Member

Откуда: Саранск
Сообщений: 578
new dev

А так?
SELECT * 
FROM Table1 
WHERE birthday>=CONVERT(DATETIME,'24.02.1982',104)
  AND birthday<CONVERT(DATETIME,'24.02.1982',104)+1
12 июл 09, 21:44    [7406197]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
а как быть с родившимися 29 февраля ?
13 июл 09, 01:21    [7406431]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Alex_Toms
Member

Откуда: Саранск
Сообщений: 578
Аналогично...
SELECT * 
FROM Table1 
WHERE Birthday>=CONVERT(SMALLDATETIME,'29.02.1984',104)
  AND Birthday<CONVERT(SMALLDATETIME,'29.02.1984',104)+1
Если смущает сложение к дате одного дня, то вторую дату +1 день можно получить и другим способом. Само собой, искомая дата должна быть корректной, в противном случае, перед запросом потребуется проверка на корректность даты.
13 июл 09, 09:13    [7406654]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
tusha
Member

Откуда:
Сообщений: 122
имхо красивее так бы было
dateadd(day,1,CONVERT(SMALLDATETIME,'29.02.1984',104))

=)
13 июл 09, 11:03    [7407239]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Alex_Toms
Member

Откуда: Саранск
Сообщений: 578
Для нашего случая, можно и так, дело вкуса.
Но есть тонкость, dateadd принимает аргумент интервала как целое, поэтому с помощью её не получится найти интервал допустим за полдня, а для других задач это будет необходимо.
13 июл 09, 11:26    [7407365]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
new dev
Member

Откуда:
Сообщений: 36
Alex_Toms
new dev

А так?
SELECT * 
FROM Table1 
WHERE birthday>=CONVERT(DATETIME,'24.02.1982',104)
  AND birthday<CONVERT(DATETIME,'24.02.1982',104)+1


Проблема в том, что нужно получить только те записи, у которых сегодня ДР, а не по конкретной дате, т.е. все записи, у которых совпадает только день и месяц с сегодняшней датой.
13 июл 09, 11:34    [7407404]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
tusha
Member

Откуда:
Сообщений: 122
тогда
getdate()
вернет тебе сегодняшнюю дату
13 июл 09, 11:35    [7407417]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
tusha
Member

Откуда:
Сообщений: 122
блин, пардон, getdate не катит) используй
month(mydate)+day(mydate)=month(getdate())+day(getdate())
13 июл 09, 11:39    [7407431]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
new dev
Alex_Toms
new dev

А так?
SELECT * 
FROM Table1 
WHERE birthday>=CONVERT(DATETIME,'24.02.1982',104)
  AND birthday<CONVERT(DATETIME,'24.02.1982',104)+1


Проблема в том, что нужно получить только те записи, у которых сегодня ДР, а не по конкретной дате, т.е. все записи, у которых совпадает только день и месяц с сегодняшней датой.
Какая же это проблема?
DATEADD(DAY,1, CONVERT(CHAR(8), GETDATE(),112))
И т.п. Или
DATEADD(DAY,1+DATEDIFF(DAY,0, GETDATE()),0)
эти два выражения дадут 0 часов завтрашнего дня. Остальные вычисления аналогично.
Имеет смысл заранее посчитать в переменных даты, которыми ограничивается запрос.
И дальше использовать только эти переменные.
13 июл 09, 11:40    [7407434]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
new dev
Member

Откуда:
Сообщений: 36
tusha
тогда
getdate()
вернет тебе сегодняшнюю дату

Это не совсем то. Пример, сегодня 2009-07-13. Нужно выбрать записи из таблицы с датами 1986-07-13, 1949-07-13, 1957-07-13, 1956-07-13, 1990-07-13... и т.д.
13 июл 09, 11:43    [7407439]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
tusha
Member

Откуда:
Сообщений: 122
мой пост выше
13 июл 09, 11:45    [7407452]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
tusha
блин, пардон, getdate не катит) используй
month(mydate)+day(mydate)=month(getdate())+day(getdate())
select month('19750102')+day('19750102') as result1
      ,month('20090201')+day('20090201') as result2

result1     result2
----------- -----------
3           3

(1 row(s) affected)


PS я за вариант aleks2 если это нужно изредка
и за варианты с выч. столбцами если это нужно часто
13 июл 09, 11:48    [7407462]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
tusha
Member

Откуда:
Сообщений: 122
протупил =)
month(mydate)*100+day(mydate)=month(getdate())*100+day(getdate())
13 июл 09, 11:50    [7407477]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
tusha
мой пост выше
А мой ещё выше
13 июл 09, 11:50    [7407478]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
vino
Member

Откуда:
Сообщений: 1191
new dev, вам iap уже дал оптимальный вариант
Все остальное будет извращением
13 июл 09, 11:54    [7407500]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
vino
Member

Откуда:
Сообщений: 1191
aleks2, вариант очень неплох, но люди больше ста лет тоже живут
13 июл 09, 11:56    [7407510]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Alex_Toms
Member

Откуда: Саранск
Сообщений: 578
new dev
Проблема в том, что нужно получить только те записи, у которых сегодня ДР, а не по конкретной дате, т.е. все записи, у которых совпадает только день и месяц с сегодняшней датой.

Нет проблем...
WHERE Birthday>=CONVERT(DATETIME,CONVERT(CHAR(10),GETDATE(),104),104) 
  AND Birthday<CONVERT(DATETIME,CONVERT(CHAR(10),GETDATE(),104),104)+1

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

iap
DATEADD(DAY,1, CONVERT(CHAR(8), GETDATE(),112))
И т.п. Или
DATEADD(DAY,1+DATEDIFF(DAY,0, GETDATE()),0)

И чем это красивее по сравнению с +1, больше кода?

iap
Имеет смысл заранее посчитать в переменных даты, которыми ограничивается запрос.
И дальше использовать только эти переменные.

Именно так я сначала и сделал. Только вот для одной тестовой таблицы оптимизатор индекс использовал, а для другой использовать отказался. Посему вариант с переменными предлагать не стал.
13 июл 09, 12:34    [7407741]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
Alex_Toms
все записи, у которых совпадает только день и месяц с сегодняшней датой.

Нет проблем...
WHERE Birthday>=CONVERT(DATETIME,CONVERT(CHAR(10),GETDATE(),104),104) 
  AND Birthday<CONVERT(DATETIME,CONVERT(CHAR(10),GETDATE(),104),104)+1
Я может чего не понимаю, но я не вижу совпадения только дня и месяца (с игнорированием года)
Я даже попробовал:
declare @t table(Birthday datetime)
insert into @t
select '19860713' union all
select '19490713' union all
select '19860715' union all
select '19490715'

-- Alex_Toms
select * from @t
WHERE Birthday>=CONVERT(DATETIME,CONVERT(CHAR(10),GETDATE(),104),104) 
  AND Birthday<CONVERT(DATETIME,CONVERT(CHAR(10),GETDATE(),104),104)+1

-- iap
select * from @t
where RIGHT(CONVERT(VARCHAR(8),Birthday,112),4) = RIGHT(CONVERT(VARCHAR(8),getdate(),112),4)
----- (computed field ^ )

Birthday
-----------------------

(0 row(s) affected)

Birthday
-----------------------
1986-07-13 00:00:00.000
1949-07-13 00:00:00.000

(2 row(s) affected)
13 июл 09, 12:47    [7407823]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Alex_Toms
Member

Откуда: Саранск
Сообщений: 578
Нужно выбрать из таблицы только те записи, у которых сегодня ДР

Хм, вообще то я понял это именно как сегодняшний день, а не как день например в прошлом году...
И пример потому такой дал, для прошлых лет он и не должен работать.
Извините погорячился...
13 июл 09, 13:02    [7407922]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
Bagyr
Member

Откуда:
Сообщений: 4
declare @d as varchar(4)
set @d = convert(varchar(4), getdate(), 4)

select *
from t
where convert(varchar(4), birthday, 112) = @d
13 июл 09, 13:53    [7408407]     Ответить | Цитировать Сообщить модератору
 Re: Определить сегодня ли ДР по дате  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Bagyr
declare @d as varchar(4)
set @d = convert(varchar(4), getdate(), 4)

select *
from t
where convert(varchar(4), birthday, 112) = @d
Ваш запрос по скорости полностью будет соответствовать скорости запроса заглавного поста этого топика.
13 июл 09, 13:55    [7408426]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить