2016-12-14 129 views
-2

我目前正试图编写一个查询来计算患者天数。我的源表中有VisitID,AdmitDateTime和DischargeDateTime。患者日定义为患者在午夜在床上。因此,例如,如果2016-01-01年有5名患者入院,而之前没有其他患者在医院就诊,那么患者日在2016-01-02将等于5。患者天计算

我想显示结果的列是日期和计数。我想过用CTE构建一个日历表,但我不确定连接应该在我的源表中。如果在某一天床上没有病人,我希望计数为0.我对SQL很陌生,所有帮助都将不胜感激。

+2

到目前为止,您尝试了什么,您的解决方案有什么问题?请阅读[帮助]中的[问]。显示出一些努力极大地增加了我们的帮助意愿 – Pred

+0

通常,您将在应用程序级代码中处理'缺少'日的逻辑。 – Strawberry

+0

@Strawberry你会吗?我遇到过这样的问题(你有记录代表日期的事件,有些日期没有事件,但是你想每天返回一个计数 - 甚至那些计数为零的记录)几次在过去并且通常发现它是在报告层中解决的,而不是应用层? – 3N1GM4

回答

0

我强烈建议使用日历表,但如果这不是您的选择,那么这里是一个使用递归CTE构建主日期列表的解决方案。

请注意,如果您的整体日期范围超过100天,由于cte递归的限制,这将不起作用。 (再次尝试使用日历表,效率会更高)

如果您不得不报告具体的月份,那么您需要更改定义[FirstDate]和[LastDate的初始cte ]

DROP TABLE #Clientvisit 

CREATE TABLE #ClientVisit(
VisitID INT 
,AdmitDateTime DATETIME 
,DischargeDateTime DATETIME 
) 

INSERT INTO #ClientVisit 
VALUES 
(1,'20160604 13:50','20160606 03:50') 
,(2,'20160604 13:50','20160609 13:50') 


--IF YOU'RE NOT USING A CALENDAR TABLE THEN USE RECURSIVE CTE TO BUILD DATE LIST 
;WITH cte 
    AS 
    (
    SELECT 
     MIN(CAST(AdmitDateTime AS DATE)) AS FirstDate 
     ,MAX(CAST(DischargeDateTime AS DATE)) AS LastDate 
    FROM 
     #ClientVisit 
    ) 
,cte_R 
    AS 
    (
    SELECT FirstDate,LastDate FROM cte 
    UNION ALL 
    SELECT DATEADD(DD,1,FirstDate),LastDate FROM cte_R 
    WHERE DATEADD(DD,1,FirstDate) <= LastDate 
    ) 
SELECT 
    c.FirstDate 
    ,COUNT(v.VisitID) AS BedDays 
FROM 
    cte_R c 
     LEFT JOIN #ClientVisit v 
      ON 
      DATEADD(DD 
        ,1 --PLAY WITH THIS VALUE EITHER -1/0/1 TO ALLIGN THE BEDDAYS WITH THE DESIRED DATE 
        ,c.FirstDate) BETWEEN v.AdmitDateTime AND v.DischargeDateTime 
GROUP BY 
    c.FirstDate