显示每天每小时的SQL
我写了下面的代码,将显示每天患者到达和离开的数据分解成每天按小时进行的患者普查 代码可以工作,但是对于每个日期,它不是为0-23小时每个添加一个小时,而是为0添加第二行,因此它将每天分成25行,而不是24行。我很确定问题出在下面的交叉应用程序中,但我包含了其余代码供您参考 我真的很感激你能给我的任何帮助。另外,如果您有任何关于如何在这里发布代码并使其看起来更正常的提示,请告诉我。谢谢大家!显示每天每小时的SQL,sql,tsql,Sql,Tsql,我写了下面的代码,将显示每天患者到达和离开的数据分解成每天按小时进行的患者普查 代码可以工作,但是对于每个日期,它不是为0-23小时每个添加一个小时,而是为0添加第二行,因此它将每天分成25行,而不是24行。我很确定问题出在下面的交叉应用程序中,但我包含了其余代码供您参考 我真的很感激你能给我的任何帮助。另外,如果您有任何关于如何在这里发布代码并使其看起来更正常的提示,请告诉我。谢谢大家! --Create my temporary table SELECT * INTO #Temporary
--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
中有单独的记录,它们的开始日期和结束日期之间有重叠的天数,那么这些日期和时间就会重复,这取决于它们共享的记录数量和天数
因此,我所做的是将来自dbo.Census
的PK添加到交叉应用
中,然后在子查询中使用该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
替换为来自dbo.Census
的PK欢迎使用堆栈溢出!您可以将文本格式化为代码,方法是将其包装为严重的重音/反引号:代码>示例`。或者,通过在文本编辑器中突出显示文本并单击文本框上方的“代码标记”按钮,将代码缩进4个空格。谢谢!虽然我试过了,但仍然会产生同样的错误。pt_id是PK,但pt_id在普查表中确实存在。小时0应该每天只填充一次,并且填充两次。例如,在日期:1月9日,我有一行时间:0,pt_id:5,startdatetime:2018-01-08 00:00,还有一行时间:0,pt_id:5,startdatetime:2018:01-09 00:00。这种情况每天都在发生。所以它一定与DateAdd有关?@sa102,你能提供一些来自dbo.Census
的样本数据吗,最好是1月9日的例子?如果你把它添加到原始问题中,并使用代码格式工具使它看起来更好,可能会更好。根据您的回答,我无法说出dbo.Census的哪些列,以及哪些数据与这些列相匹配。谢谢。我是这样添加的。@sa102因为pt_id不是唯一的,而且似乎没有其他唯一字段,所以您需要向#Temporary
添加唯一的键。最简单的方法是将行编号()
粘贴到填充的查询中。
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