我有一张表格如下:
PatientID DiseaseCode DiseaseDate
1 xhd8 23-5-2006
1 nxhd 07-9-2013
2 kdeh 15-3-1998
其中:
如何编写单个查询,告诉我这位患者(#1)是否仍然主动诊断为糖尿病患者,逻辑应如下: 病人有xhd8吗?如果是 - >他有nxhd(治愈)吗? - > 后他被诊断出来了吗?如果是 - >不告诉我患者,如果他没有解决代码,或者在诊断之前记录为已解决,则告诉我患者。
在上面的例子中,患者糖尿病在诊断后已经解决(治愈),所以它不会返回任何东西。但是在下面的例子中,我希望能够返回患者记录:PatientID DiseaseCode DiseaseDate
1 xhd8 23-8-2014
1 nxhd 09-3-1996
2 kdeh 15-3-1998
遗憾的是,更改数据库架构超出了我的允许范围。
欢迎并赞赏任何想法。
答案 0 :(得分:0)
NOT EXISTS
应该做到这一点。请注意我的例子和评论。
DECLARE @table TABLE (PatientID int, DiseaseCode varchar(10), DiseaseDate date);
INSERT @table VALUES
(1,'xhd8','20060523'),
(1,'nxhd','20130907'),
(2,'kdeh','19980315');
-- Should return nothing
SELECT *
FROM @table t
WHERE t.DiseaseCode = 'xhd8'
AND NOT EXISTS
(
SELECT 1
FROM @table t2
WHERE t.PatientID = t2.PatientID
AND t2.DiseaseCode = 'nxhd'
AND t2.DiseaseDate > t.DiseaseDate
);
DELETE FROM @table;
INSERT @table VALUES
(1,'xhd8','20140823'),
(1,'nxhd','19960309'),
(2,'kdeh','19980315');
-- should return employee ID=1 with diseaseCode = 'xhd8'
SELECT *
FROM @table t
WHERE t.DiseaseCode = 'xhd8'
AND NOT EXISTS
(
SELECT 1
FROM @table t2
WHERE t.PatientID = t2.PatientID
AND t2.DiseaseCode = 'nxhd'
AND t2.DiseaseDate > t.DiseaseDate
);
答案 1 :(得分:0)
如果我理解正确,你可以试试这个:
SET DATEFORMAT DMY;
DECLARE @tbl TABLE(PatientID INT,DiseaseCode VARCHAR(10), DiseaseDate DATE);
INSERT INTO @tbl VALUES
(1,'xhd8','23-5-2006')
,(1,'nxhd','07-9-2013')
,(2,'kdeh','15-3-1998');
SELECT MostCurrenntDiabetes.*
FROM
(
SELECT TOP 1 WITH TIES t.*
FROM @tbl t
WHERE t.DiseaseCode IN('xhd8','nxhd')
ORDER BY ROW_NUMBER() OVER(PARTITION BY t.PatientID ORDER BY t.DiseaseDate DESC)
) AS MostCurrenntDiabetes
--WHERE MostCurrenntDiabetes.DiseaseCode='xhd8';
将SELECT TOP 1 WITH TIES
与ROW_NUMBER() OVER(PARTITION BY ...)
一起使用会返回排序等级为1
的所有行。这意味着,您将获得每位患者的最后一个(最年轻的)行。
内部WHERE
中的SELECT
将减少患有任何糖尿病相关疾病代码的患者的行(其他任何疾病代码都不会显示在最后。
最终WHERE
将仅返回这些患者,其中最年轻代码为 xhd8 。我评论过这个,以避免空集。
你可能需要别的东西......