#sql #tsql
#sql #tsql
Вопрос:
Почему сравнение работает странно в этом примере? Даты, которые являются днями рождения, являются:
1990-03-22
1998-03-20
1990-03-22
2002-12-02
2004-03-18
2004-03-20
2004-03-25
Я делаю это
WHERE DATEADD(YY, 18, jun.birth_date) >= DATEADD(YY, 1, GETDATE())
Который, я думаю, должен отсечь все записи людей старше 18 лет через год с сегодняшнего дня. Но это абсолютно противоположно, вот что я получаю:
2004-03-18
2004-03-20
2004-03-25
И я получаю правильные результаты, когда я просматриваю записи меньше и даже больше, чем дата в следующем году.
Почему это так работает?
Комментарии:
1. Если вам нужны люди, которым сегодня исполнилось 18 лет или больше, зачем добавлять год к
GETDATE
?2. На английском языке этот SQL говорит; где 18-й день рождения — это год или больше в будущем.
Ответ №1:
Это то, что у вас есть…
WHERE
someone's date of birth 18 years
>=
Today's date 1 year
На английском языке это; where the 18th birthday is a year or more in the future.
Я думаю, что вы действительно хотите (если вам нужны люди старше 18 лет)… WHERE the birthdate is earlier than today's date minus 18 years
(18 или более лет назад)
WHERE
Jun.birth_date <= DATEADD(YY, -18, GETDATE())
Ответ №2:
Если вам нужны люди, которым сегодня исполнилось 18 лет или больше, то сегодня отнимите 18 лет, не добавляйте годы в столбец DoB, так как это делает запрос не подлежащим обработке:
SELECT birth_date
FROM dbo.YourTable
WHERE birth_date <= DATEADD(YEAR, -18, CONVERT(date,GETDATE()));
Ответ №3:
Почему вы не используете datediff
, вместо dateadd
?
with d as (
select cast('1990-03-22' as date) as birthDate union all
select cast('1998-03-20' as date) as birthDate union all
select cast('1990-03-22' as date) as birthDate union all
select cast('2002-12-02' as date) as birthDate union all
select cast('2004-03-18' as date) as birthDate union all
select cast('2004-03-20' as date) as birthDate union all
select cast('2004-03-25' as date) as birthDate
)
select *
from d
where datediff(year,birthDate, getdate()) >= 18
Так проще понять поведение.
Комментарии:
1. «Почему бы вам не использовать
datediff
, вместоdateadd
?» потому что это все еще невозможно.2. @Larnu, насколько я вижу в вопросе, это не проблема. Если это не так, для меня гораздо проще понять этот запрос, используя
datediff
вместоdateadd
.3. Применение функций к искомому столбцу — плохая привычка. Однажды наученный, трудно отучить. Я согласен, что это функционально правильно и НЕМНОГО проще для понимания, но что касается SQL, я считаю, что это все еще анти-шаблон, и поэтому я согласен с Larnu.
Born on or before 18 years ago
вряд ли это сложная концепция, даже еслиAge >= 18
ЭТО тривиальная концепция.4. Привет @MatBailie. Я понимаю, почему лучше избегать использования функций для поиска по столбцу, но я только что сказал, что в зависимости от размера данных это может быть проблемой или нет. И если запрос легче понять, возможно, оправдано его оплатить, учитывая, что стоимость может быть нулевой.
5. Чтобы привести ссылку на @JaimeDrq: From
datediff
: »int
Разница между начальной и конечной датой, выраженная в границе, установленной datepart «. В этом случае границей является изменение года, например, 2020-12-31 и 2021-01-01 разделены одним годом. 2020-01-01 и 2021-12-31 также разделены одним годом.