1

Microsoft SQL Server r2には、次のような入院患者の入院データがあります。

PatientID, AdmitDate,        DischargeDate
Jones.     1-jan-13 01:37.   1-jan-13 17:45
Smith      1-jan-13 02:12.   2-jan-13 02:14
Brooks.    4-jan-13 13:54.   5-jan-13 06:14

病院にいる​​患者の数を日ごとに、時間ごとに数えたいのですが(つまり、

1-jan-13 00:00. 0
1-jan-13 01:00. 0
1-jan-13 02:00. 1
1-jan-13 03:00. 2

そして、結果に入院している患者がいない時間を含める必要があります。

ただし、テーブルを作成できないため、すべての時間と曜日をリストした参照テーブルを作成することはできません。

助言がありますか?

4

4 に答える 4

1

これが1つの(醜い)方法です:

;WITH DayHours AS
(
    SELECT 0 DayHour
    UNION ALL
    SELECT DayHour+1
    FROM DayHours
    WHERE DayHour+1 <= 23
)
SELECT B.AdmitDate, A.DayHour, COUNT(DISTINCT PatientID) Patients
FROM DayHours A
CROSS JOIN (SELECT DISTINCT CONVERT(DATE,AdmitDate) AdmitDate
            FROM YourTable) B
LEFT JOIN YourTable C
    ON B.AdmitDate = CONVERT(DATE,C.AdmitDate)
    AND A.DayHour = DATEPART(HOUR,C.AdmitDate)
GROUP BY B.AdmitDate, A.DayHour
于 2013-01-29T14:09:09.310 に答える
1

この問題を解決するには、日時のリストが必要です。以下は、24時間のテーブルにクロス結合された承認日からこれを取得します。24時間の表はinformation_schema.columns、SQLServerで数値の小さなシーケンスを取得するためのトリックから計算されています。

残りは、このテーブルと時間の間の単なる結合です。このバージョンでは、その時間に患者がカウントされるため、たとえば、同じ時間に入院および退院した人はカウントされません。そして一般的に、誰かが入院してから次の1時間まで数えられません。

with dh as (
     select DATEADD(hour, seqnum - 1, thedatehour ) as DateHour
     from (select distinct cast(cast(AdmitDate as DATE) as datetime) as thedatehour
           from Admission a
          ) a cross join
          (select ROW_NUMBER() over (order by (select NULL)) as seqnum
           from INFORMATION_SCHEMA.COLUMNS
          ) hours
          where hours <= 24
    )
select dh.DateHour, COUNT(*) as NumPatients
from dh join
     Admissions a
     on dh.DateHour between a.AdmitDate and a.DischargeDate
group by dh.DateHour
order by 1

これはまた、毎日入場があることを前提としています。それは合理的な仮定のようです。そうでない場合は、カレンダーテーブルが大いに役立ちます。

于 2013-01-29T14:26:12.550 に答える
1

これは少し面倒で、提供したテストデータを含む一時テーブルが含まれていますが

    CREATE TABLE #HospitalPatientData (PatientId NVARCHAR(MAX), AdmitDate DATETIME, DischargeDate DATETIME)
INSERT INTO #HospitalPatientData
SELECT 'Jones.',     '1-jan-13 01:37:00.000',   '1-jan-13 17:45:00.000' UNION
SELECT 'Smith',      '1-jan-13 02:12:00.000',   '2-jan-13 02:14:00.000' UNION
SELECT 'Brooks.',    '4-jan-13 13:54:00.000',  '5-jan-13 06:14:00.000'

;WITH DayHours AS
(
    SELECT 0 DayHour
    UNION ALL
    SELECT DayHour+1
    FROM DayHours
    WHERE DayHour+1 <= 23
),
HospitalPatientData AS
(
SELECT CONVERT(nvarchar(max),AdmitDate,103) as AdmitDate ,DATEPART(hour,(AdmitDate)) as     AdmitHour, COUNT(PatientID) as CountOfPatients
FROM #HospitalPatientData
GROUP BY CONVERT(nvarchar(max),AdmitDate,103), DATEPART(hour,(AdmitDate))
),
Results AS
(
SELECT MAX(h.AdmitDate) as Date, d.DayHour
FROM HospitalPatientData h
INNER JOIN DayHours d ON d.DayHour=d.DayHour
GROUP BY AdmitDate, CountOfPatients, DayHour
)

SELECT r.*, COUNT(h.PatientId) as CountOfPatients
FROM Results r
LEFT JOIN #HospitalPatientData h ON CONVERT(nvarchar(max),AdmitDate,103)=r.Date AND     DATEPART(HOUR,h.AdmitDate)=r.DayHour
GROUP BY r.Date, r.DayHour
ORDER BY r.Date, r.DayHour

DROP TABLE #HospitalPatientData
于 2013-01-29T14:47:28.100 に答える
0

これはあなたが始めるかもしれません:

BEGIN TRAN

DECLARE @pt TABLE
    (
      PatientID VARCHAR(10)
    , AdmitDate DATETIME
    , DischargeDate DATETIME
    )

INSERT  INTO @pt
        ( PatientID, AdmitDate, DischargeDate )
VALUES  ( 'Jones', '1-jan-13 01:37', '1-jan-13 17:45' ),
        ( 'Smith', '1-jan-13 02:12', '2-jan-13 02:14' )
,       ( 'Brooks', '4-jan-13 13:54', '5-jan-13 06:14' )



DECLARE @StartDate DATETIME = '20130101'
    , @FutureDays INT = 7


;
WITH    dy
          AS ( SELECT TOP (@FutureDays)
                        ROW_NUMBER() OVER ( ORDER BY name ) dy
               FROM     sys.columns c
             ) ,
        hr
          AS ( SELECT TOP 24
                        ROW_NUMBER() OVER ( ORDER BY name ) hr
               FROM     sys.columns c
             )
    SELECT  refDate, COUNT(p.PatientID) AS PtCount
    FROM    ( SELECT    DATEADD(HOUR, hr.hr - 1,
                                DATEADD(DAY, dy.dy - 1, @StartDate)) AS refDate
              FROM      dy
                        CROSS JOIN hr
            ) ref
    LEFT JOIN @pt p ON ref.refDate BETWEEN p.AdmitDate AND p.DischargeDate        
    GROUP BY refDate

ORDER BY refDate

ROLLBACK
于 2013-01-29T14:22:44.680 に答える