2016-12-14 127 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