我的SQL查询中有一个场景,我必须找出具有给定日期但来自多年的婴儿记录假设我的选择日期是 = 01/Jan/2014 to 31/Jan/2014
我还有一个参数是年份,它要求我随机选择以前(1~3 岁)出生的婴儿的数据假设如果我当前的选定日期是 2014 年,并且我的年份变量的值为 2,则
我必须将婴儿的数据分别带到当年,并且比当前日期少一年,依此类推以下是我的给定场景
--------------------------------------------
-- BABIES_TABLE
ID | Name | Age | DOB |
--------------------------------------------
1 JKL 3 21/Jan/2012
2 DEF 2 09/Jan/2013
3 ABC 1 04/Jan/2014
4 XYZ 1 02/Feb/2014
-- Date Range [01/Jan/2014 - 31/Jan/2014]
-- Year = 2
---------------------------------------------
ID | Name | Age | DOB |
---------------------------------------------
3 ABC 1 04/Jan/2014
2 DEF 2 09/Jan/2013
-- Date Range [01/Jan/2014 - 31/Jan/2014]
-- Year = 3
---------------------------------------------
ID | Name | Age | DOB |
---------------------------------------------
3 ABC 1 04/Jan/2014
2 DEF 2 09/Jan/2013
1 JKL 3 21/Jan/2012
下面是我的 SQl 查询,它模棱两可且有错误。我尝试过单日期比较,很好但是当我添加OR条件时,它会给我错误
--MY SQL Query is Below
DECLARE @startDate AS DATETIME
DECLARE @enddate AS DATETIME
DECLARE @y AS INT
SET @startDate='2012-10-12'
SET @enddate='2012-10-20'
SET @y=2
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= CASE
--If entered Year = 1
WHEN @y = 1 THEN
(@startDate)
--If entered Year = 2
WHEN @y = 2 THEN
CASE
(@startDate)
END
OR
CASE
YEAR(@startDate-1)
END
WHEN @y = 3 THEN
CASE
(@startDate)
END
OR
CASE
YEAR(@startDate-1)
END
OR
CASE
YEAR(@startDate-2)
END
END
END
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= CASE
WHEN @y = 1 THEN
(@enddate)
WHEN @y = 2 THEN
CASE
(@enddate)
END
OR
CASE
YEAR(@enddate-1)
END
WHEN @y = 3 THEN
CASE
(@enddate)
END
OR
CASE
YEAR(@enddate-1)
END
OR
CASE
YEAR(@enddate-2)
END
END
END
这是我达到的预期结果,但我想在何处使用案例是可能的。
---------------------------------------------
ID | Name | Age | DOB |
--------------------------------------------
1 Abid 6 2008-01-01
2 Zahid 6 2008-01-10
3 Laila 5 2009-01-15
4 Ali 5 2010-01-26
5 Kali 4 2011-01-19
6 Sali 3 2012-01-08
7 Brone 2 2013-01-11
8 Dilche 2 2013-01-29
9 Alpechino 3 2012-08-20
这是我的存储过程。
--MY SQL Query is Below
CREATE PROCEDURE BabyUnionData
@Year AS INT,
@Start_Date as varchar(30),
@End_Date as Varchar(30)
AS
BEGIN
DECLARE @startDate AS DATETIME
DECLARE @enddate AS DATETIME
DECLARE @y AS INT
SET @startDate=@Start_Date
SET @enddate=@End_Date
--SELECt * FROM BABIES_TABLE
PRINT 'For One Year'
SET @y=@Year
IF @y = 1
BEGIN
PRINT 'For One Year'
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= @startDate
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= @enddate
END
ELSE IF @y = 2
BEGIN
PRINT 'For Two Years'
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= @startDate
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= @enddate
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-1,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-1,@enddate)
END
ELSE IF @y = 3
BEGIN
PRINT 'For Three Years'
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= @startDate
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= @enddate
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-1,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-1,@enddate)
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-2,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-2,@enddate)
END
ELSE IF @y = 4
BEGIN
PRINT 'For Four Years'
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= @startDate
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= @enddate
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-1,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-1,@enddate)
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-2,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-2,@enddate)
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-3,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-3,@enddate)
END
ELSE IF @y = 5
BEGIN
PRINT 'For Five Years'
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= @startDate
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= @enddate
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-1,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-1,@enddate)
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-2,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-2,@enddate)
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-3,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-3,@enddate)
UNION
SELECT * FROM BABIES_TABLE
WHERE
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= DATEADD(Year,-4,@startDate)
AND
CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEADD(Year,-4,@enddate)
END
END
--这是存储过程的使用
Exec BabyUnionData 5,'01-01-2014','01-31-2014'
我有与 Vittore 相同的解决方案,然后想,问题是我没有按照我的理解遵循您的要求。当今天开始日期结束日期和上一年的结束日期之间是 1 时
这是我有一个不可靠的解决方案
create table #y (y tinyint)
insert into #y values (1)
insert into #y values (2)
insert into #y values (3)
DECLARE @startDate AS DATETIME
DECLARE @enddate AS DATETIME
DECLARE @y AS INT
SET @startDate='2012-10-12'
SET @enddate='2012-10-20'
SET @y=2
SELECT *
FROM BABIES_TABLE
cross join #y
WHERE CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) >= datediff(year, y - 1, @startdate )
AND CAST(CONVERT(VARCHAR, BABIES_TABLE.DOB, 111) AS DATETIME) <= DATEDIFF(year, y - 1, @enddate )
and y <= @y
也许使用 cte 是可能的
更新
我有这个想法,以防您需要特定的日期测试,而不是很久。例如,在 y=2 的情况下,您希望 dob =
规范化您的开始和结束日期,以及当前年份的 DOB
SET @startDate=DATEADD(yy, YEAR(@startDate)-YEAR(getdate()), @startDate)
SET @enddate=DATEADD(yy, YEAR(@enddate)-YEAR(getdate()), @enddate)
select * from babies where
Age >= @y -- check that baby is old enough
and DATEADD(yy, YEAR(dob)-YEAR(getdate()), dob) between @startDate and @enddate - and the DOB is within a range in a year.