尝试针对每条记录显示上次访问日期

时间:2017-11-11 10:10:05

标签: sql sql-server tsql date

我有一组访问记录,我正在尝试根据相同的数据集编制一些其他信息:

data table

我试图在每一行上添加一列,根据实际日期给出当前记录之前的日期,所以第二行将报告第一行实际日期,第三行报告第二行等...我希望第一个报告NULL

我已使用以下SQL

为首次访问和上次访问创建了列
(SELECT TOP 1 v2.ACTUALDATE 
from VISITS v2 
   LEFT JOIN TRVISIT tv2 ON v2.VISID = tv2.VISID 
WHERE tv2.TRAINEEID = trv.TRAINEEID 
ORDER BY v2.ACTUALDATE) as FirstVisit,

(SELECT TOP 1 v2.ACTUALDATE 
 from VISITS v2 
   LEFT JOIN TRVISIT tv2 ON v2.VISID = tv2.VISID 
 WHERE tv2.TRAINEEID = trv.TRAINEEID 
 ORDER BY v2.ACTUALDATE DESC) as LASTVisit,

编辑*这是使用MS SQL Server 2012,生成数据涉及两个表

表1 TRVISIT包含以下内容: TRAINEEID,VISID

表2 VISITS包含以下内容: VISID,VISITTYPE,PLANDATE,PLANEDNDATE,ACTUALDATE,ACTUALENDDATE,NOTES

我正在尝试创建一个视图,允许我为每个TRAINEEID报告一次访问列表,其中包含每次访问的个别数据以及其他列: -VisitCount每位受训者的访问次数 -ReviewCount每位受训者的特定访问类型计数 -FirstVisit第一次访问发生的日期 - 访问上次访问的日期 - 先前访问当前记录中访问之前发生的访问日期。

完整代码:

SELECT 

--Link Data
trv.TRAINEEID,

--Visit Data
trv.VISID,
v.VISITTYPE,
v.PLANDATE,
v.PLANENDDATE,
v.ACTUALDATE,
v.ACTUALENDDATE,

v.NOTES,

(SELECT COUNT(*) FROM TRVISIT t2 WHERE t2.TRAINEEID = trv.TRAINEEID) AS VisitCount,
(SELECT COUNT(case WHEN v2.VISITTYPE = 'R' then 1 else null end) FROM TRVISIT tv2 LEFT JOIN VISITS v2 ON tv2.VISID = v2.VISID WHERE tv2.TRAINEEID = trv.TRAINEEID) AS ReviewCount,
(SELECT TOP 1 v2.ACTUALDATE from VISITS v2 LEFT JOIN TRVISIT tv2 ON v2.VISID = tv2.VISID WHERE tv2.TRAINEEID = trv.TRAINEEID ORDER BY v2.ACTUALDATE) as FirstVisit,
(SELECT TOP 1 v2.ACTUALDATE from VISITS v2 LEFT JOIN TRVISIT tv2 ON v2.VISID = tv2.VISID WHERE tv2.TRAINEEID = trv.TRAINEEID ORDER BY v2.ACTUALDATE DESC) as LASTVisit,
(SELECT LAG(v2.ACTUALDATE, 1) OVER(PARTITION BY tv2.TRAINEEID ORDER BY v2.ACTUALDATE ASC) from VISITS v2 LEFT JOIN TRVISIT tv2 ON v2.VISID = tv2.VISID WHERE tv2.TRAINEEID = trv.TRAINEEID) as PrevVist,

COUNT(*) OVER () as Total_Rows

FROM TRVISIT trv
LEFT JOIN VISITS v on trv.VISID = v.VISID

ORDER BY v.ACTUALDATE

1 个答案:

答案 0 :(得分:0)

有一大堆window functions使用over子句,不仅限于lag函数。您可以利用这些而不是为您想要的每个聚合求助于多个子查询。

以下答案可以为您提供所需的一切。

select tv.traineeid
, v.plandate
, v.planenddate
, v.actualdate
, v.actualenddate
, count(v.visid) over (partition by tv.traineeid) as VisitCount
, sum(case when tv.visittype = 'R' then 1 else 0 end) over (partition by tv.traineeid) as ReviewCount
, min(v.actualdate) over (partition by tv.traineeid) as FirstVisit
, max(v.actualdate) over (partition by tv.traineeid) as LastVisit
, lag(v.actualdate, 1, NULL) over (partition by tv.traineeid order by v.actualdate asc) as PrevVisit
from trvisit as tv
left join visits as v on tv.visid = v.visid