personsID traindate expirationdate trainingID
-------------------------------------------------------------------
1 1/1/2014 null 3
1 2/1/2014 null 3
1 3/1/2014 4/1/2014 3
1 4/1/2014 4/30/2014 4
1 5/1/2014 5/30/2014 4
我一直试图弄清楚如何写这个查询好几天了,但还没有成功。我已经尝试过案例,(NULLIF(MAX(COALESCE(,max,子查询和其他几个,但无法弄清楚如何返回我需要的结果。
我需要查询要做的是根据到期日期和培训日期为每个培训ID返回1行。换句话说,查询需要首先查看expirationdate列,如果值为null,则检索最后一个traindate。如果expirationdate不为null,则返回最后的expirationdate。在上面的例子中,我需要结果:
personsID traindate expirationdate trainingID
--------------------------------------------------------------------
1 2/1/2014 null 3
1 5/1/2014 5/30/2014 4
非常感谢任何帮助。
答案 0 :(得分:1)
如果我的假设(请参阅问题评论)是正确的,那么这将在SQL Server中执行。
编辑:OP澄清是需要的。我已经以两种不同的方式包含了他想要的结果,但我认为我更喜欢选项2。DECLARE @tbl TABLE(personsID INT
,traindate DATE
,expirationdate DATE
,trainingID INT)
INSERT INTO @tbl VALUES
(1,'1/1/2014',null,3)
,(1,'2/1/2014',null,3)
,(1,'3/1/2014','4/1/2014',3)
,(1,'4/1/2014','4/30/2014',4)
,(1,'5/1/2014','5/30/2014',4)
SELECT personsID
,trainingID
,CASE WHEN EXISTS(SELECT 1
FROM @tbl a
WHERE a.personsID=b.personsID
AND a.trainingID =b.trainingID
AND a.expirationdate IS NULL)
THEN (SELECT MAX(traindate)
FROM @tbl a
WHERE a.personsID=b.personsID
AND a.trainingID =b.trainingID
AND a.expirationdate IS NULL )
ELSE MAX(traindate)
END maxtraindatethatdoesntexpire_option1
,(SELECT TOP 1
traindate
FROM @tbl a
WHERE a.personsID=b.personsID
AND a.trainingID =b.trainingID
ORDER BY CASE WHEN a.expirationdate IS NULL THEN 1 ELSE 0 END DESC
,traindate DESC
) maxtraindatethatdoesntexpire_option2
,CASE WHEN EXISTS(SELECT 1
FROM @tbl a
WHERE a.personsID=b.personsID
AND a.trainingID =b.trainingID
AND a.expirationdate IS NULL)
THEN NULL
ELSE MAX(expirationdate)
END expirationdate
FROM @tbl b
GROUP BY personsID,trainingID
ORIGINAL:
棘手的部分是使用CASE WHEN EXISTS来处理NULL到期日期。除此之外,它看起来像是
的问题DECLARE @tbl TABLE(personsID INT
,traindate DATE
,expirationdate DATE
,trainingID INT)
INSERT INTO @tbl VALUES
(1,'1/1/2014',null,3)
,(1,'2/1/2014',null,3)
,(1,'3/1/2014','4/1/2014',3)
,(1,'4/1/2014','4/30/2014',4)
,(1,'5/1/2014','5/30/2014',4)
SELECT personsID
,trainingID
,MAX(traindate) traindate
,CASE WHEN EXISTS(SELECT 1
FROM @tbl a
WHERE a.personsID=b.personsID
AND a.trainingID =b.trainingID
AND a.expirationdate IS NULL)
THEN NULL
ELSE MAX(expirationdate)
END expirationdate
FROM @tbl b
GROUP BY personsID,trainingID