DateDiff 缺少几条记录

发布于 2024-12-06 18:41:27 字数 744 浏览 3 评论 0原文

我正在使用 datediff 函数

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

由于 Between 运算符无效,我还将代码更改为是否

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

I am using the datediff function

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

Since the between operator is not effective I have also changed the code to

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

Is there any other effective way to write datediff to capture all the missing records?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

与往事干杯 2024-12-13 18:41:28

这些记录应该丢失,因为 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

尽管从技术上讲,这并不能执行正确的计算,因为它只找到年份值的差异,而不考虑日期和月份。例如,出生日期为 1990 年 12 月 31 日,入职日期为 1/1/2008,即使该人只有 17 岁零 1 天,也会登记为 18 岁。我建议使用这个问题中提供的解决方案:

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

Those records should be missing because the number of years between stDob and stJoinDt is not between 18 and 75, as you are filtering them out with your condition that stDob and stJoinDt differ by between 18 and 75 years:

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

Output:

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)

My guess would be you were wanting to capture all records where the person is at least 18 years old. In that case, remove the 75 part from the filter:

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

Although technically this does not perform the correct calculation, because it is only finding the difference in the year values and not taking into account day and month. For instance, a date-of-birth of 12/31/1990 and a join date of 1/1/2008 would register as 18 years even though the person is only 17 years, 1 day old. I would recommend instead using the solution provided in this question:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文