DateDiff Отсутствует несколько записей - PullRequest
0 голосов
/ 27 сентября 2011

Я использую функцию datediff

SELECT stName
       ,stId
       ,stDob  --(varchar(15))
       ,stJoinDt --(datetime)
FROM student stu
WHERE
DATEDIFF(yy,stu.stDob,stu.stJoinDt) between 18 and 75

Поскольку оператор before не действует, я также изменил код на

SELECT stName
           ,stId
           ,stDob
           ,stJoinDt
    FROM student stu
    WHERE
    DATEDIFF(yy,stu.stDob,stu.stJoinDt) >= 18 
    AND  DATEDIFF(yy,stu.stDob,stu.stJoinDt) < 75

Есть ли другой эффективный способ записи datediffзахватить все недостающие записи?

The missing records are
stDob             stJoinDt
10/08/1925        2011-01-03
04/18/1935        2011-01-19
12/11/1928        2011-06-06
1/24/1927         2011-04-18
04/18/1918        2011-04-20

1 Ответ

2 голосов
/ 27 сентября 2011

Эти записи должны отсутствовать, потому что число лет между stDob и stJoinDt составляет , а не между 18 и 75, поскольку вы фильтруете их с вашим условием, что stDob и stJoinDt различаютсямежду 18 и 75 годами:

with student as (
    select 'Bob' as stName, 1 as stId, '10/08/1925' as stDob,        '2011-01-03' as stJoinDt
    union select 'Bob' as stName, 2 as stId, '04/18/1935',        '2011-01-19'
    union select 'Bob' as stName, 3 as stId, '12/11/1928',        '2011-06-06'
    union select 'Bob' as stName, 4 as stId, '1/24/1927 ',        '2011-04-18'
    union select 'Bob' as stName, 5 as stId, '04/18/1918',        '2011-04-20'
)
    SELECT stName
           ,stId
           ,stDob  --(varchar(15))
           ,stJoinDt --(datetime)
           ,datediff(yy, stu.stDob, stu.stJoinDt) as DiffYears
    FROM student stu

Вывод:

stName  stId    stDob           stJoinDt    DiffYears
Bob     1       10/08/1925      2011-01-03  *86* (>75)
Bob     2       04/18/1935      2011-01-19  *76* (>75)
Bob     3       12/11/1928      2011-06-06  *83* (>75)
Bob     4       1/24/1927       2011-04-18  *84* (>75)
Bob     5       04/18/1918      2011-04-20  *93* (>75)

Я думаю, вы хотели бы захватить все записи, где человеку не менее 18 лет.В этом случае удалите деталь 75 из фильтра:

WHERE
DATEDIFF(yy,stu.stDob,stu.stJoinDt) >= 18 
-- STOP HERE

Хотя технически это не дает правильного расчета, поскольку он только находит разницу в значениях года и не учитывает день и месяц,Например, дата рождения 31.12.1990 и дата вступления 01.01.2008 будут зарегистрированы как 18 лет, даже если человеку всего 17 лет, 1 день.Я бы рекомендовал вместо этого использовать решение, предоставленное в этом вопросе :

where
    (DATEDIFF(YY, stu.stDob, stu.stJoinDt) -
        CASE WHEN( 
            (MONTH(stDob)*100 + DAY(stDob)) > (MONTH(stJoinDt)*100 + DAY(stJoinDt))
        ) THEN 1 ELSE 0 END
    ) >= 18
...