这些是患者去医院的日期:
NAME DISCHARGEDATE
---------------------
Eva 1/1/17
Eva 1/10/17
Eva 2/8/17
我需要患者访问医院的日期列表以及他们访问医院的最近一次约会,如下所示:
NAME DISCHARGEDATE PREVIOUSDISCHARGEDATE
-----------------------------------------------
Eva 1/1/17 NULL
Eva 1/10/17 1/1/17
Eva 2/8/17 1/10/17
我一直在尝试RowNum()和Top 1以及相关的子查询,我无法得到它。谢谢。
这是我为现实写的脚本,它返回患者的访问,但是对于第二个表中的所有字段都是“NULL”:
SELECT
ad.Name,
ad.DischargeDate,
PrevDisch.DischargeDate as PrevDischDate
FROM
AbstractData AS ad
LEFT JOIN
(SELECT TOP 1
DischargeDate, UnitNumber, VisitID
FROM
AbstractData AS ad2
WHERE
SourceID = 'BLD'
AND PtStatus in ('IN', 'INO')
AND DischargeDateTime > @ReadmitStartDate
--AND ad2.DischargeDate < ad.DischargeDate
ORDER BY
UnitNumber, DischargeDate) AS PrevDisch ON ad.UnitNumber = PrevDisch.UnitNumber
AND PrevDisch.DischargeDate < ad.DischargeDate
AND PrevDisch.DischargeDate IS NOT NULL
WHERE
ad.Name = 'Eva'
答案 0 :(得分:3)
您可以使用 LAG()
Declare @YourTable table (NAME varchar(25),DISCHARGEDATE date)
Insert Into @YourTable values
('Eva','2017-01-01'),
('Eva','2017-10-01'),
('Eva','2017-02-08')
Select A.*
,PREVIOUSDISCHARGEDATE = Lag(DISCHARGEDATE,1) over (Partition By Name Order by DISCHARGEDATE)
From @YourTable A
返回
NAME DISCHARGEDATE PREVIOUSDISCHARGEDATE
Eva 2017-01-01 NULL
Eva 2017-02-08 2017-01-01
Eva 2017-10-01 2017-02-08
编辑 - 替代LAG()
;with cte as (
Select *
,RN = Row_Number() over (Partition By Name Order by DISCHARGEDATE)
From @YourTable
)
Select A.*
,PREVIOUSDISCHARGEDATE = B.DISCHARGEDATE
From cte A
Left Join cte B a.name=B.name and on A.RN=B.RN+1
答案 1 :(得分:0)
我知道John Cappelletti已经使用LAG()提供了答案。但是想尝试一个加入解决方案的解决方案。如果有人需要它而没有LAG(),将来可能会。这个解决方案似乎有点麻烦,但它可以达到目的。
Declare @YourTable table (NAME varchar(25),DISCHARGEDATE date)
Insert Into @YourTable values
('Eva','2017-01-01'),
('Eva','2017-10-01'),
('Eva','2017-02-08')
SELECT NAME,DISCHARGEDATE,MAX(PREVIOUS) AS PREVIOUS_DISCHARGE
FROM
(SELECT NAME,DISCHARGEDATE,'NULL' AS PREVIOUS
FROM
(SELECT NAME
,DISCHARGEDATE
,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY DISCHARGEDATE) RN FROM @YourTable) M
WHERE M.RN=1
UNION ALL
SELECT X.NAME,X.DISCHARGEDATE,CONVERT(VARCHAR(10),Y.DISCHARGEDATE)
FROM
(SELECT NAME
,DISCHARGEDATE
,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY DISCHARGEDATE) RN FROM @YourTable) X
INNER JOIN
(SELECT NAME
,DISCHARGEDATE
,(ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY DISCHARGEDATE)-1) RN FROM @YourTable) Y
ON X.RN > Y.RN) OUTERR
WHERE CONVERT(VARCHAR(10),DISCHARGEDATE) <> PREVIOUS
GROUP BY NAME,DISCHARGEDATE
ORDER BY NAME