我有一些这样的示例数据:
DECLARE @T Table (ID INT, Name VARCHAR(10), DOB DATE)
INSERT INTO @T (ID, Name, DOB) VALUES (1,'Mohan', '1937-12-01')
INSERT INTO @T (ID, Name, DOB) VALUES (2,'Raj', '1936-12-25')
INSERT INTO @T (ID, Name, DOB) VALUES (5,'Manny', '1937-01-30')
INSERT INTO @T (ID, Name, DOB) VALUES (3,'kamal', '1938-12-12')
INSERT INTO @T (ID, Name, DOB) VALUES (4,'Raj', '1937-05-12')
SELECT * FROM @T
通过使用以下查询,我将找到年,月,日的年龄
SELECT Name,cast((DATEDIFF(m, DOB, GETDATE())/12) as varchar) + ' Y & ' +
cast((DATEDIFF(m, DOB, GETDATE())%12) as varchar) + ' M & ' +
cast((DATEDIFF(D, DOB, GETDATE())%12) as varchar) + ' d' from @T
我只是想知道未来45天内谁将达到78,79和80岁。
通过使用以下查询,我可以获得在未来45天内达到80年的数据
where
DOB > DATEADD(year,-80,GETDATE()) and
DOB < DATEADD(year,-80,DATEADD(day,45,GETDATE()))
如果我通过80,它将一次提供一个数据,这将给出数据达到80年。如果我给出79,它将给出达到79年的数据。
但是我怎样才能在45天内达到78,79和80年的所有数据。
建议我最好的方式
Name Age
Mohan 78 Y & 11 M & 9 d
Raj 79 Y & 11 M & 2 d
kamal 77 Y & 11 M & 5 d
以上人员在45天内达到各自的年份
Mohan 79 --> with in 45 days
Raj 80 --> with in 45 days
kamal 78 --> with in 45 days
答案 0 :(得分:2)
要查找生日在接下来的45天内的所有人,通常最简单的方法是重置您在一年内比较的所有值,然后从那里开始工作:
DECLARE @T Table (ID INT,Name VARCHAR(10),DOB DATE)
INSERT INTO @T (ID,Name,DOB) VALUES (1,'Mohan','1937-12-01')
INSERT INTO @T (ID,Name,DOB) VALUES (2,'Raj','1936-12-25')
INSERT INTO @T (ID,Name,DOB) VALUES (5,'Manny','1937-01-30')
INSERT INTO @T (ID,Name,DOB) VALUES (3,'kamal','1938-12-12')
INSERT INTO @T (ID,Name,DOB) VALUES (4,'Raj','1937-05-12')
declare @Today date
--Set "Today" to today's date in 2000
set @Today = DATEADD(year,DATEDIFF(year,GETDATE(),'20000101'),GETDATE())
declare @Plus45 date
set @Plus45 = DATEADD(day,45,@Today)
--And reset to 2000 (year wrap-around)
set @Plus45 = DATEADD(year,DATEDIFF(year,@Plus45,'20000101'),@Plus45)
select @Today as Today,@Plus45 as Plus45
;With ResetDOBs as (
select
*,
DATEADD(year,DATEDIFF(year,DOB,'20000101'),DOB) as DOB2000
from
@T
)
select
*
from
ResetDOBs
where
DOB2000 between @Today and @Plus45 or
(@Plus45 < @Today and
(DOB2000 <= @Plus45 or DOB2000 >= @Today)
)
结果:
ID Name DOB DOB2000
----------- ---------- ---------- ----------
1 Mohan 1937-12-01 2000-12-01
3 kamal 1938-12-12 2000-12-12
如果它是闰年,我们可以使用任何一年进行重置。我选择2000.在计算@Plus45
和最后的Where
条款中,当45天的时间与年终转换重叠时,使用这种方法处理奇怪的事情还有一点点麻烦。 ,十二月/一月。
(在我的时区,它目前是2016-11-09,所以Raj(ID 2)还没有完全在45天的窗口内)
此查询:
SELECT Name,cast((DATEDIFF(m, DOB, GETDATE())/12) as varchar) + ' Y & ' +
cast((DATEDIFF(m, DOB, GETDATE())%12) as varchar) + ' M & ' +
cast((DATEDIFF(D, DOB, GETDATE())%12) as varchar) + ' d' from @T
仍然严重受伤。 Raj(身份证2)不会将他们的年龄报告为79岁和以上。 11 M&amp; 2 d,正如您所报告的那样。他们将年龄报告为79岁,10个月和几天。您的月计算很容易超过1,并且您的日计算会混淆(为什么%12
计算一天?)。
这是进行Y / M / D计算的一种方法,应该更接近人们对人们年龄的期望。如果你有一个数字表,你可以用它来创建NumPairs
CTE,而不是我在这里创建它的方式:
DECLARE @T Table (ID INT,Name VARCHAR(10),DOB DATE)
INSERT INTO @T (ID,Name,DOB) VALUES (1,'Mohan','1937-12-01')
INSERT INTO @T (ID,Name,DOB) VALUES (2,'Raj','1936-12-25')
INSERT INTO @T (ID,Name,DOB) VALUES (5,'Manny','1937-01-30')
INSERT INTO @T (ID,Name,DOB) VALUES (3,'kamal','1938-12-12')
INSERT INTO @T (ID,Name,DOB) VALUES (4,'Raj','1937-05-12')
declare @Today date
set @today = GETDATE()
;With NumPairs as (
select 0 as n1, 1 as n2
union all
select n1+1,n2+1
from NumPairs
where n1 <= 150
)
select
t.*,
y.n1 as Y,
m.n1 as M,
d.n1 as D
from
@T t
cross apply
(select n1,DATEADD(year,n1,DOB) as DOBy from NumPairs
where DATEADD(year,n1,DOB) <= @today and
DATEADD(year,n2,DOB) > @today
) y
cross apply
(select n1,DATEADD(month,n1,DOBy) as DOBmy from NumPairs
where DATEADD(month,n1,DOBy) <= @today and
DATEADD(month,n2,DOBy) > @today
) m
cross apply
(select n1 from NumPairs
where DATEADD(day,n1,DOBmy) = @today
) d
option (maxrecursion 0)
结果:
ID Name DOB Y M D
----------- ---------- ---------- ----------- ----------- -----------
3 kamal 1938-12-12 77 10 28
1 Mohan 1937-12-01 78 11 8
2 Raj 1936-12-25 79 10 15
5 Manny 1937-01-30 79 9 10
4 Raj 1937-05-12 79 5 28
答案 1 :(得分:1)
您可以先计算下一个年龄和下一个生日的天数,然后按它们进行过滤。
WITH y AS
(
SELECT *,
DATEDIFF(hour,DOB,GETDATE())/8766 + 1 NextAge,
DATEDIFF(DAY, GETDATE(), DATEADD(YEAR, DATEDIFF(hour,DOB,GETDATE())/8766 + 1, DOB)) ToNextBirthday
FROM @T
)
SELECT * FROM y
WHERE
y.NextAge IN (78, 79, 80)
AND y.ToNextBirthday <= 45
上述答案会在评论中提到的一些边缘案例中出现问题。
下面我借用this answer中的代码来计算NextAge
。其余的逻辑仍然是相同的。
DECLARE @today DATE;
SET @today = GETDATE();
WITH a AS
(
SELECT *,
(CONVERT(int,CONVERT(char(8), @today, 112))-CONVERT(char(8), DOB, 112))/10000 + 1 NextAge
FROM @T
), b AS
(
SELECT *,
DATEDIFF(DAY, @today, DATEADD(YEAR, a.NextAge, DOB)) ToNextBirthday
FROM a
)
SELECT * FROM b
WHERE
b.NextAge IN (78, 79, 80)
AND b.ToNextBirthday <= 45
答案 2 :(得分:1)
我只想知道即将到来的78,79和80岁的人 45天。
有一种更简单的方法来查看问题。你有一个日期范围:
[today, today + 45 days]
您需要检查某人是否在这些范围内有出生日期:
[today - 78 years, today + 45 days - 78 years]
[today - 79 years, today + 45 days - 79 years]
[today - 80 years, today + 45 days - 80 years]
查询只是变成:
DECLARE @D0 AS DATE = CURRENT_TIMESTAMP -- 2016-11-09
DECLARE @D1 AS DATE = DATEADD(DAY, 45, CURRENT_TIMESTAMP) -- 2016-12-24
SELECT *
FROM @T
WHERE DOB BETWEEN DATEADD(YEAR, -78, @D0) AND DATEADD(YEAR, -78, @D1)
OR DOB BETWEEN DATEADD(YEAR, -79, @D0) AND DATEADD(YEAR, -79, @D1)
OR DOB BETWEEN DATEADD(YEAR, -80, @D0) AND DATEADD(YEAR, -80, @D1)
答案 3 :(得分:0)
where
DOB > DATEADD(year,-80,GETDATE()) and
DOB < DATEADD(year,-80,DATEADD(day,45,GETDATE()))
如果这样做,你可以添加一些'或子句'来实现你想要的东西(如果我做对了):
where
(DOB > DATEADD(year,-80,GETDATE()) and
DOB < DATEADD(year,-80,DATEADD(day,45,GETDATE())))
or
(DOB > DATEADD(year,-79,GETDATE()) and
DOB < DATEADD(year,-79,DATEADD(day,45,GETDATE())))
...
答案 4 :(得分:0)
SELECT * from @T
WHERE
(DATEDIFF(dd,GETDATE(),DATEADD(yy,78,dob))<45
AND
DATEDIFF(dd,GETDATE(),DATEADD(yy,78,dob))>0)
OR
(DATEDIFF(dd,GETDATE(),DATEADD(yy,79,dob))<45
AND
DATEDIFF(dd,GETDATE(),DATEADD(yy,79,dob))>0)
OR
(DATEDIFF(dd,GETDATE(),DATEADD(yy,80,dob))<45
AND
DATEDIFF(dd,GETDATE(),DATEADD(yy,80,dob))>0)
答案 5 :(得分:0)
尝试
DECLARE @T Table (ID INT,Name VARCHAR(10),DOB DATE)
INSERT INTO @T (ID,Name,DOB) VALUES (1,'Mohan','1937-12-01')
INSERT INTO @T (ID,Name,DOB) VALUES (2,'Raj','1936-12-25')
INSERT INTO @T (ID,Name,DOB) VALUES (5,'Manny','1937-01-30')
INSERT INTO @T (ID,Name,DOB) VALUES (3,'kamal','1938-12-12')
INSERT INTO @T (ID,Name,DOB) VALUES (4,'Raj','1937-05-12')
declare @dd date = dateadd(day,45,getdate());
declare @dmd int = month(@dd)*100+day(@dd);
select @dd, @dmd;
select *
from @T
where datediff(year, DOB, @dd) - case when month(DOB)*100+day(DOB) > @dmd then 1 else 0 end in (78,79,80)
order by DOB;
答案 6 :(得分:0)
我曾经使用SQL函数来计算年龄,我希望它也可以帮助你满足你的要求。
但是你的问题还有一个方面,你想提前45天看到
因此,我们需要在现在添加45天,然后calculate age in SQL
,而不是计算当前日期的年龄。我是这样做的
DECLARE @T Table (ID INT, Name VARCHAR(10), DOB DATE)
INSERT INTO @T (ID, Name, DOB) VALUES (1,'Mohan', '1937-12-01')
INSERT INTO @T (ID, Name, DOB) VALUES (2,'Raj', '1936-12-25')
INSERT INTO @T (ID, Name, DOB) VALUES (5,'Manny', '1937-01-30')
INSERT INTO @T (ID, Name, DOB) VALUES (3,'kamal', '1938-12-12')
INSERT INTO @T (ID, Name, DOB) VALUES (4,'Raj', '1937-05-12')
INSERT INTO @T (ID, Name, DOB) VALUES (3,'kodyaz', '2015-12-25')
INSERT INTO @T (ID, Name, DOB) VALUES (3,'eralper', '2015-12-24')
SELECT
*,
dbo.fn_CalculateAge(DOB,dateadd(dd,45,getdate())) fo
FROM @T
--where
--dbo.fn_CalculateAge(DOB,dateadd(dd,45,getdate())) = 79 and
--dbo.fn_CalculateAge(DOB,getdate()) = 78
请注意,如果您取消注释WHERE子句,您将获得现在为78岁且在45天内为79岁的人
我希望它有所帮助,