我编写了以下代码,以分解我的数据,该数据显示每天的患者出入情况,每天按小时进行一次患者普查。
该代码有效,但是对于每个日期,它不会为0-23的每个小时增加一个小时,而是为0添加第二行,因此它每天分成25行而不是24行。我很确定问题在下面的“交叉应用”中,但是我提供了其余代码供您参考。
非常感谢您能提供的任何帮助。另外,如果您对如何在此处发布代码有任何建议,并使代码看起来更正常,请告诉我。谢谢!
--Create my temporary table
SELECT *
INTO #Temporary
FROM dbo.Census
WHERE YEAR(startdatetime) >= 2018
ORDER BY
startdatetime
,pt_id
--Use the Cross Apply to split out every day into every hour
SELECT
Date = CAST(D AS DATE)
,Hour = DATEPART(HOUR, D)
,pt_id
,cendate
,locationid
,[room-bed]
,startdatetime
,enddatetime
,minutes
,DayOfWeek
,WeekInt
,MyStartMinutes = 0
,MyEndMinutes = 0
INTO #Temporary2
FROM #Temporary A
CROSS APPLY
(
SELECT TOP ( ABS(DATEDIFF(HOUR, A.startdatetime, A.enddatetime) + 1))
D = DATEADD(HOUR, -1 + ROW_NUMBER() OVER ( ORDER BY ( SELECT NULL )), A.startdatetime)
FROM master..spt_values n1
,master..spt_values n2
) B
--Update values for MyStartMinutes and MyEndMinutes
UPDATE #Temporary2
SET MyStartMinutes = CASE WHEN ( DATEPART(HOUR, startdatetime) = Hour )
THEN DATEPART(mi, enddatetime)
ELSE 0 END
UPDATE #Temporary2
SET MyEndMinutes = CASE WHEN ( DATEPART(HOUR, enddatetime) = Hour )
AND DATEDIFF(DAY, enddatetime, cendate) = 0
THEN DATEPART(mi, enddatetime)
ELSE 0 END
--Update values of startdatetime and enddatetime
UPDATE #Temporary2
SET startdatetime = DATEADD(HOUR, Hour, DATEADD(MINUTE, MyStartMinutes, CAST(CAST(startdatetime AS DATE) AS DATETIME)))
UPDATE #Temporary2
SET enddatetime = CASE WHEN ( Hour < 23 )
THEN ( DATEADD(HOUR, Hour + 1, DATEADD(MINUTE, MyEndMinutes, CAST(CAST(startdatetime AS DATE) AS DATETIME))))
WHEN Hour = 23
THEN ( DATEADD(HOUR, 0, DATEADD(MINUTE, MyEndMinutes, CAST(CAST(enddatetime AS DATE) AS DATETIME))))
ELSE '' END
--Update Value of Minutes
UPDATE #Temporary2
SET Minutes = DATEDIFF(mi, startdatetime, enddatetime)
SELECT *
FROM #Temporary2
ORDER BY minutes DESC
以下是dbo.Census
的示例数据:
org pt_id cendate location bed startdate enddate minutes DOW
A 5 1/8/2018 7E 50 1/8/2018 8:00 1/9/2018 0:00 960 Mon
A 5 1/9/2018 7E 50 1/9/2018 0:00 1/10/2018 0:00 1440 Tue
A 5 1/10/2018 7E 50 1/10/2018 0:00 1/11/2018 0:00 1440 Wed
A 5 1/11/2018 7E 50 1/11/2018 0:00 1/11/2018 14:00 840 Thu
A 1 10/17/2016 ED 10 10/17/2016 1:05 10/17/2016 10:21 556 Mon
A 2 5/10/2017 4L 20 5/10/2017 15:09 5/11/2017 0:00 531 Wed
A 3 5/14/2017 4L 30 5/14/2017 0:00 5/14/2017 8:12 492 Sun
A 4 6/3/2017 5C 40 6/3/2017 0:00 6/4/2017 0:00 1440 Sat
答案 0 :(得分:1)
我认为您的CROSS APPLY
是罪魁祸首是正确的。在根据我自己的示例数据测试代码之后,我发现如果dbo.Census
中有单独的记录,它们的开始日期和结束日期之间有重叠的天数,则这些日期和时间将被重复,具体取决于多少条记录和多少条记录他们分享的日子。
所以我要做的是将dbo.Census
中的PK添加到CROSS APPLY
中,然后在子查询中使用该id列将结果仅过滤到那些ID匹配的结果。这是我更改的代码部分:
SELECT
Date = CAST(D AS DATE)
,Hour = DATEPART(HOUR, D)
,A.pt_id
,cendate
,locationid
,[room-bed]
,startdatetime
,enddatetime
,minutes
,DayOfWeek
,WeekInt
,MyStartMinutes = 0
,MyEndMinutes = 0
INTO #Temporary2
FROM #Temporary A
CROSS APPLY
(
SELECT TOP ( ABS(DATEDIFF(HOUR, A.startdatetime, A.enddatetime) + 1))
D = DATEADD(HOUR, -1 + ROW_NUMBER() OVER ( ORDER BY ( SELECT NULL )), A.startdatetime)
,A.pt_id
FROM master..spt_values n1
,master..spt_values n2
) B
WHERE A.pt_id = B.pt_id
我假设pt_id
是dbo.Census
的主键。如果不是这种情况,您只需将pt_id
的PK替换为dbo.Census
。