获取员工的生日 +-30 天
Get Birthdates of employees for a period of +-30 days
我是 SQL 的新手。对于我的 SAP 附加组件,我需要一个 SQL 查询来显示员工的生日 +-30 天(这将是最后给定 int 的用户)。我根据自己的理解写了一个查询,它只限制了当月的时间段。 Ex:If 当前日期是 2016.01.15 正确的查询应该显示出生日期在 12 月 16 日到 2 月 14 日之间。但是我只看到January.You的生日可以看到下面的查询
SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1],
T0.[E_MailL] FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode
WHERE DATEADD( Year, DATEPART( Year, GETDATE()) - DATEPART( Year, T0.[BirthDate]),
T0.[BirthDate]) BETWEEN CONVERT( DATE, GETDATE()-30)AND CONVERT( DATE, GETDATE() +30);
我应该做哪些更改才能获得正确的结果?
任何帮助将不胜感激! :-)
我对此进行了一些简化。我已经在进行计算的代码中添加了注释,以便将来回顾时您会知道它在做什么(通常是救世主):)。
SELECT T0.[BirthDate],
T0.[CardCode],
T1.[CardName],
T0.[Name],
T0.[Tel1],
T0.[E_MailL]
FROM OCPR T0
INNER JOIN OCRD T1
ON T0.CardCode = T1.CardCode
WHERE T0.[BirthDate] >= GETDATE() -- Where the birthday is greater than or equal to today's date
AND T0.[BirthDate] <= GETDATE() + 30 -- Where the birthday is less than or equal to today's date plus 30 days.
这样的事情怎么样:
SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1], T0.[E_MailL]
FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode
WHERE TO.[BirthDate] BETWEEN DATEADD(DAY, -30, GETDATE()) AND DATEADD(DAY, +30, GETDATE())
您可以在评论中修改answer I've referenced如下:
SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1], T0.[E_MailL]
FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode
WHERE 1 = (FLOOR(DATEDIFF(dd,TO.Birthdate,GETDATE()+30) / 365.25))
-
(FLOOR(DATEDIFF(dd,TO.Birthdate,GETDATE()-30) / 365.25))
根据 Vladimir 的评论,如果需要,您可以将“365.25”修改为“365.2425”以获得更高的准确性。
我在SQL服务器上测试过,因为它有DATEADD
、GETDATE
的功能。
当 +-30 天的范围跨越 1 月 1 日时,即当范围属于两年时,您的查询 returns 错误结果。
你的计算
DATEADD(Year, DATEPART(Year, GETDATE()) - DATEPART( Year, T0.[BirthDate]), T0.[BirthDate])
将 BirthDate
的年份移动到与 GETDATE
相同的年份,因此如果 GETDATE
returns 2016-01-01
,则 BirthDate=1957-12-25
变成 2016-12-25
。但是你的范围是从2015-12-01
到2016-01-30
,调整后的BirthDate
不在其中。
有很多方法可以考虑这一年界线。
一个可能的变体是不从 2015-12-01
到 2016-01-30
设置一个范围,而是设置三个 - 对于未来几年和前几年也是如此:
from `2014-12-01` to `2015-01-30`
from `2015-12-01` to `2016-01-30`
from `2016-12-01` to `2017-01-30`
请注意 - 最好将原始 BirthDate
与某些计算结果进行比较,而不是转换 BirthDate
并比较函数的结果。在第一种情况下优化器可以在 BirthDate
上使用索引,在第二种情况下它不能。
这是我在 SQL Server 2008 中测试的完整示例。
DECLARE @T TABLE (BirthDate date);
INSERT INTO @T (BirthDate) VALUES
('2016-12-25'),
('2016-01-25'),
('2016-02-25'),
('2016-11-25'),
('2015-12-25'),
('2015-01-25'),
('2015-02-25'),
('2015-11-25'),
('2014-12-25'),
('2014-01-25'),
('2014-02-25'),
('2014-11-25');
--DECLARE @CurrDate date = '2016-01-01';
DECLARE @CurrDate date = '2015-12-31';
DECLARE @VarDays int = 30;
我使用变量 @CurrDate
而不是 GETDATE
来检查它在不同情况下的工作方式。
DATEDIFF(year, @CurrDate, BirthDate)
是 @CurrDate
和 BirthDate
之间的年差
DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate)
@CurrDate
与 BirthDate
同年搬入
最后的DATEADD(day, -@VarDays, ...)
和DATEADD(day, +@VarDays, ...)
的范围为+-@VarDays
。
此范围在 "main" 以及之前和之后的年份创建了三次。
SELECT
BirthDate
FROM @T
WHERE
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate))
)
OR
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)+1, @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)+1, @CurrDate))
)
OR
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)-1, @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)-1, @CurrDate))
)
;
结果
+------------+
| BirthDate |
+------------+
| 2016-12-25 |
| 2016-01-25 |
| 2015-12-25 |
| 2015-01-25 |
| 2014-12-25 |
| 2014-01-25 |
+------------+
您可以尝试使用 DAYOFYEAR:
SELECT T0.[BirthDate],
T0.[CardCode],
T1.[CardName],
T0.[Name],
T0.[Tel1],
T0.[E_MailL]
FROM OCPR T0
INNER JOIN OCRD T1
ON T0.CardCode = T1.CardCode
WHERE IF(DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE()) < 0, DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE()) + DayOfYear(DATE_FORMAT(CURDATE(),"%Y-12-31")), DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE())) <= 30
OR IF(DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate]) < 0, DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate]) + DayOfYear(DATE_FORMAT(CURDATE(),"%Y-12-31")), DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate])) <= 30
我是 SQL 的新手。对于我的 SAP 附加组件,我需要一个 SQL 查询来显示员工的生日 +-30 天(这将是最后给定 int 的用户)。我根据自己的理解写了一个查询,它只限制了当月的时间段。 Ex:If 当前日期是 2016.01.15 正确的查询应该显示出生日期在 12 月 16 日到 2 月 14 日之间。但是我只看到January.You的生日可以看到下面的查询
SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1],
T0.[E_MailL] FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode
WHERE DATEADD( Year, DATEPART( Year, GETDATE()) - DATEPART( Year, T0.[BirthDate]),
T0.[BirthDate]) BETWEEN CONVERT( DATE, GETDATE()-30)AND CONVERT( DATE, GETDATE() +30);
我应该做哪些更改才能获得正确的结果? 任何帮助将不胜感激! :-)
我对此进行了一些简化。我已经在进行计算的代码中添加了注释,以便将来回顾时您会知道它在做什么(通常是救世主):)。
SELECT T0.[BirthDate],
T0.[CardCode],
T1.[CardName],
T0.[Name],
T0.[Tel1],
T0.[E_MailL]
FROM OCPR T0
INNER JOIN OCRD T1
ON T0.CardCode = T1.CardCode
WHERE T0.[BirthDate] >= GETDATE() -- Where the birthday is greater than or equal to today's date
AND T0.[BirthDate] <= GETDATE() + 30 -- Where the birthday is less than or equal to today's date plus 30 days.
这样的事情怎么样:
SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1], T0.[E_MailL]
FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode
WHERE TO.[BirthDate] BETWEEN DATEADD(DAY, -30, GETDATE()) AND DATEADD(DAY, +30, GETDATE())
您可以在评论中修改answer I've referenced如下:
SELECT T0.[BirthDate], T0.[CardCode], T1.[CardName], T0.[Name], T0.[Tel1], T0.[E_MailL]
FROM OCPR T0 INNER JOIN OCRD T1 ON T0.CardCode = T1.CardCode
WHERE 1 = (FLOOR(DATEDIFF(dd,TO.Birthdate,GETDATE()+30) / 365.25))
-
(FLOOR(DATEDIFF(dd,TO.Birthdate,GETDATE()-30) / 365.25))
根据 Vladimir 的评论,如果需要,您可以将“365.25”修改为“365.2425”以获得更高的准确性。
我在SQL服务器上测试过,因为它有DATEADD
、GETDATE
的功能。
当 +-30 天的范围跨越 1 月 1 日时,即当范围属于两年时,您的查询 returns 错误结果。
你的计算
DATEADD(Year, DATEPART(Year, GETDATE()) - DATEPART( Year, T0.[BirthDate]), T0.[BirthDate])
将 BirthDate
的年份移动到与 GETDATE
相同的年份,因此如果 GETDATE
returns 2016-01-01
,则 BirthDate=1957-12-25
变成 2016-12-25
。但是你的范围是从2015-12-01
到2016-01-30
,调整后的BirthDate
不在其中。
有很多方法可以考虑这一年界线。
一个可能的变体是不从 2015-12-01
到 2016-01-30
设置一个范围,而是设置三个 - 对于未来几年和前几年也是如此:
from `2014-12-01` to `2015-01-30`
from `2015-12-01` to `2016-01-30`
from `2016-12-01` to `2017-01-30`
请注意 - 最好将原始 BirthDate
与某些计算结果进行比较,而不是转换 BirthDate
并比较函数的结果。在第一种情况下优化器可以在 BirthDate
上使用索引,在第二种情况下它不能。
这是我在 SQL Server 2008 中测试的完整示例。
DECLARE @T TABLE (BirthDate date);
INSERT INTO @T (BirthDate) VALUES
('2016-12-25'),
('2016-01-25'),
('2016-02-25'),
('2016-11-25'),
('2015-12-25'),
('2015-01-25'),
('2015-02-25'),
('2015-11-25'),
('2014-12-25'),
('2014-01-25'),
('2014-02-25'),
('2014-11-25');
--DECLARE @CurrDate date = '2016-01-01';
DECLARE @CurrDate date = '2015-12-31';
DECLARE @VarDays int = 30;
我使用变量 @CurrDate
而不是 GETDATE
来检查它在不同情况下的工作方式。
DATEDIFF(year, @CurrDate, BirthDate)
是 @CurrDate
和 BirthDate
DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate)
@CurrDate
与 BirthDate
最后的DATEADD(day, -@VarDays, ...)
和DATEADD(day, +@VarDays, ...)
的范围为+-@VarDays
。
此范围在 "main" 以及之前和之后的年份创建了三次。
SELECT
BirthDate
FROM @T
WHERE
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate))
)
OR
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)+1, @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)+1, @CurrDate))
)
OR
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)-1, @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)-1, @CurrDate))
)
;
结果
+------------+
| BirthDate |
+------------+
| 2016-12-25 |
| 2016-01-25 |
| 2015-12-25 |
| 2015-01-25 |
| 2014-12-25 |
| 2014-01-25 |
+------------+
您可以尝试使用 DAYOFYEAR:
SELECT T0.[BirthDate],
T0.[CardCode],
T1.[CardName],
T0.[Name],
T0.[Tel1],
T0.[E_MailL]
FROM OCPR T0
INNER JOIN OCRD T1
ON T0.CardCode = T1.CardCode
WHERE IF(DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE()) < 0, DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE()) + DayOfYear(DATE_FORMAT(CURDATE(),"%Y-12-31")), DayOfYear(T0.[BirthDate]) - DayOfYear(CURDATE())) <= 30
OR IF(DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate]) < 0, DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate]) + DayOfYear(DATE_FORMAT(CURDATE(),"%Y-12-31")), DayOfYear(CURDATE()) - DayOfYear(T0.[BirthDate])) <= 30