下面是一个很久以前写的存储过程。是否可以将其转换为表值函数?或者有没有更好的方法或途径可以考虑替代它?
目标是“作为一名报告分析师,我希望能够报告可配置的人口普查点在可配置的天数内的病房停留情况。”
如果我输入 01/01/2023 的
StartDate
(在幕后包含 DateTime
,只是不好的命名)和 01/01/2023 的 EndDate
(相同,实际上是一个日期时间)和下午 2 点的时间生成的数据集将计算这些日期之间的所有活动。
示例
这可能不是特定于某一天的,因此例如我可能想查看一周(7 天)的值,因此如果我在第 1 天再次到达并且一周后仍然在那里,则循环将记录为每天在人口普查时间活跃,例如 01、02、03、04、05、06、07 的@2pm。
最终目标是查看可配置期间内特定时间活跃的所有用户的数据集。
正如我所说,下面的工作当前完成,但所使用的对象不再可以使用我们现在使用的对象进行复制,并且这已经完成,但我问题是否可以使用不同的方法(例如表格)更好地完成这项工作-值函数。
ALTER PROCEDURE [dbo].[HEY_spWardStaysAtCensusDate]
@StartDate DATE,
@EndDate DATE,
@CensusTime TIME
AS
DECLARE @NoOfDays INT,
@LoopCounter INT,
@CensusDate DATETIME
SELECT
@NoOfDays = DATEDIFF(DAY, @StartDate, @EndDate) + 1
IF OBJECT_ID('tempdb..#WardStays') IS NOT NULL
BEGIN
DROP TABLE #WardStays
END
CREATE TABLE #WardStays
(
WARD_STAY_UNIQUE_ID INT NOT NULL,
CENSUS_DATE_TIME DATETIME NOT NULL,
LOCAL_PATIENT_NUMBER VARCHAR(50) NULL,
WARD_CODE VARCHAR(50) NULL,
WARD_START_DATE_TIME DATETIME NULL,
WARD_END_DATE_TIME DATETIME NULL,
TRUST_SITE_LOCAL VARCHAR(50) NULL,
TRUST_SITE_NATIONAL VARCHAR(50) NULL,
WARD_STAY_COUNTER INT NULL
)
SELECT @LoopCounter = 1
WHILE @LoopCounter <= @NoOfDays
BEGIN
SET @CensusDate = DATEADD(DAY, @LoopCounter - 1, @StartDate) + CAST(@CensusTime AS DATETIME)
INSERT INTO #WardStays (WARD_STAY_UNIQUE_ID, CENSUS_DATE_TIME, LOCAL_PATIENT_NUMBER, WARD_CODE, WARD_START_DATE_TIME,
WARD_END_DATE_TIME, TRUST_SITE_LOCAL, TRUST_SITE_NATIONAL, WARD_STAY_COUNTER)
SELECT
IPWardStayID, @CensusDate, HEYNo, WardCode,
WardStartDateTime, WardEndDateTime, HospitalCode,
HospitalNatCode, 1
FROM
HealthBI_Views.dbo.IP_WARD_STAY
WHERE
WardStartDateTime <= @CensusDate
AND (WardEndDateTime >= @CensusDate OR WardEndDateTime IS NULL)
SET @LoopCounter = @LoopCounter + 1
END
SELECT
WARD_STAY_UNIQUE_ID, CENSUS_DATE_TIME,
LOCAL_PATIENT_NUMBER, WARD_CODE,
WARD_START_DATE_TIME, WARD_END_DATE_TIME,
TRUST_SITE_LOCAL, TRUST_SITE_NATIONAL, WARD_STAY_COUNTER
FROM
#WardStays
您可以很容易地转换它。您需要做的就是用对
GENERATE_SERIES
的调用替换循环。在旧版本的 SQL Server 中,您可以使用内联数字函数,例如其中一个。
然后计算
datetime
内的 APPLY
值,最后计算 JOIN
主表。
CREATE OR ALTER FUNCTION dbo.HEY_spWardStaysAtCensusDate (
@StartDate DATE,
@EndDate DATE,
@CensusTime TIME
)
RETURNS TABLE
AS RETURN
SELECT
WARD_STAY_UNIQUE_ID = IPWardStayID,
v.CENSUS_DATE_TIME,
LOCAL_PATIENT_NUMBER = HEYNo,
WARD_CODE = WardCode,
WARD_START_DATE_TIME = WardStartDateTime,
WARD_END_DATE_TIME = WardEndDateTime,
TRUST_SITE_LOCAL = HospitalCode,
TRUST_SITE_NATIONAL = HospitalNatCode,
WARD_STAY_COUNTER = 1
FROM
GENERATE_SERIES(0, DATEDIFF(DAY, @StartDate, @EndDate)) g
CROSS APPLY (
SELECT CENSUS_DATE_TIME =
DATEADD(day, g.value, @StartDate) + CAST(@CensusTime AS DATETIME)
) v
JOIN
HealthBI_Views.dbo.IP_WARD_STAY
ON WardStartDateTime <= v.CENSUS_DATE_TIME
AND (WardEndDateTime >= v.CENSUS_DATE_TIME OR WardEndDateTime IS NULL)
;