这是我的表格:
对于Patient Arrive的每个实例,我需要一个其他状态的实例。正如您在此特定情景中所看到的,我有3个患者到达输入;因此,我的状态应如下表2所示:
这是我到目前为止所做的。
DECLARE @Patient_Leave TABLE
(
id INT,
status VARCHAR (200)
,times VARCHAR (200)
)
DECLARE @arrive INT = 0
DECLARE @Leave INT
set @Patient_Leave = (select ((select COUNT(status) FROM Parameters VF WITH (NOLOCK) where status ='Patient Arrive) -
(select COUNT(status) FROM Parameters VF WITH (NOLOCK) where status='Patient leave')))
WHILE ( @arrive ) < @Leave
BEGIN
INSERT INTO @Patient_Leave
select distinct id, status, (select 'No data entered')as Time FROM Parameters VF WITH (NOLOCK) where status='Patient Leave
SET @arrive = @arrive + 1
END
SELECT * FROM @Patient_Leave
GO
答案 0 :(得分:0)
Bethony,
我根据您提供的数据构建了以下内容并测试成功。
SQL代码:
USE SO_Tests
GO
--CREATE TABLE Patient_Table
-- (
-- id INT
-- ,status VARCHAR (200)
-- ,times VARCHAR(200)
-- )
TRUNCATE TABLE Patient_Table
INSERT INTO
Patient_Table
(ID, status, times)
VALUES
(123666,'Patient Arrive', '20180606 10:52')
,(123666,'Patient Arrive', '20180606 11:21')
,(123666,'Patient Arrive', '20180606 11:45')
,(123666,'Patient Prepped', '20180606 10:52')
,(123666,'Patient Prepped', '20180606 11:45')
,(123666,'Patient Leave', '20180606 10:52')
,(123666,'Patient Return', '20180606 10:55')
,(123666,'Patient Return', '20180606 12:30')
,(123666,'Patient Ready', '20180606 12:45')
,(123666,'Patient Discharged', '20180606 12:45')
SELECT * FROM Patient_Table
DECLARE @Count_Arrive INT = (SELECT COUNT(*) FROM Patient_Table WHERE status = 'Patient Arrive')
DECLARE @Count_Leave INT = (SELECT COUNT(*) FROM Patient_Table WHERE status = 'Patient Leave')
DECLARE @Count_Prepped INT = (SELECT COUNT(*) FROM Patient_Table WHERE status = 'Patient Prepped')
DECLARE @Count_Return INT = (SELECT COUNT(*) FROM Patient_Table WHERE status = 'Patient Return')
DECLARE @Count_Discharged INT = (SELECT COUNT(*) FROM Patient_Table WHERE status = 'Patient Discharged')
DECLARE @Count_Ready INT = (SELECT COUNT(*) FROM Patient_Table WHERE status = 'Patient Ready')
WHILE(@Count_Arrive <> @Count_Leave OR @Count_Arrive <> @Count_Prepped OR @Count_Arrive <> @Count_Return OR @Count_Arrive <> @Count_Discharged OR @Count_Arrive <> @Count_Ready)
BEGIN
IF (@Count_Arrive <> @Count_Leave)
BEGIN
INSERT INTO
Patient_Table
SELECT
123456,
'Patient Leave',
'No Data Provided'
SET @Count_Leave = @Count_Leave + 1
END
IF (@Count_Arrive <> @Count_Prepped)
BEGIN
INSERT INTO
Patient_Table
SELECT
123456,
'Patient Prepped',
'No Data Provided'
SET @Count_Prepped = @Count_Prepped + 1
END
IF (@Count_Arrive <> @Count_Return)
BEGIN
INSERT INTO
Patient_Table
SELECT
123456,
'Patient Return',
'No Data Provided'
SET @Count_Return = @Count_Return + 1
END
IF (@Count_Arrive <> @Count_Discharged)
BEGIN
INSERT INTO
Patient_Table
SELECT
123456,
'Patient Discharged',
'No Data Provided'
SET @Count_Discharged = @Count_Discharged + 1
END
IF (@Count_Arrive <> @Count_Ready)
BEGIN
INSERT INTO
Patient_Table
SELECT
123456,
'Patient Ready',
'No Data Provided'
SET @Count_Ready = @Count_Ready + 1
END
END
SELECT * FROM Patient_Table ORDER BY STATUS
这涵盖了所需的其他状态,并将虚拟行应用于到达行的计数
<强>更新强> 在光标中添加以进行患者ID并添加一些额外的处理以防止添加从未记录过的行并避免无限循环,如果另一个状态的行数超过Patient_Arrive每个id
USE SO_Tests
GO
DECLARE @Patient_Table TABLE
(
id INT
,status VARCHAR (200)
,times VARCHAR(200)
)
--TRUNCATE TABLE Patient_Table
--INSERT INTO
-- Patient_Table
-- (ID, status, times)
--VALUES
-- (123666,'Patient Arrive', '20180606 10:52')
-- ,(123666,'Patient Arrive', '20180606 11:21')
-- ,(123666,'Patient Arrive', '20180606 11:45')
-- ,(123666,'Patient Prepped', '20180606 10:52')
-- ,(123666,'Patient Prepped', '20180606 11:45')
-- ,(123666,'Patient Leave', '20180606 10:52')
-- ,(123666,'Patient Return', '20180606 10:55')
-- ,(123666,'Patient Return', '20180606 12:30')
-- ,(123666,'Patient Ready', '20180606 12:45')
-- ,(123666,'Patient Discharged', '20180606 12:45')
INSERT INTO @Patient_Table SELECT * FROM Patient_Table
DECLARE @id INT
DECLARE Patient_Cursor CURSOR FOR
SELECT
id
FROM
@Patient_Table
OPEN Patient_Cursor
FETCH NEXT FROM Patient_Cursor INTO @id
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @Count_Arrive INT = (SELECT COUNT(*) FROM @Patient_Table WHERE status = 'Patient Arrive' AND id = @id)
DECLARE @Count_Leave INT = (SELECT COUNT(*) FROM @Patient_Table WHERE status = 'Patient Leave' AND id = @id)
DECLARE @Count_Prepped INT = (SELECT COUNT(*) FROM @Patient_Table WHERE status = 'Patient Prepped' AND id = @id)
DECLARE @Count_Return INT = (SELECT COUNT(*) FROM @Patient_Table WHERE status = 'Patient Return' AND id = @id)
DECLARE @Count_Discharged INT = (SELECT COUNT(*) FROM @Patient_Table WHERE status = 'Patient Discharged' AND id = @id)
DECLARE @Count_Ready INT = (SELECT COUNT(*) FROM @Patient_Table WHERE status = 'Patient Ready' AND id = @id)
WHILE((@Count_Arrive > @Count_Leave and @Count_Leave > 0) OR (@Count_Arrive > @Count_Prepped and @Count_Prepped > 0) OR (@Count_Arrive > @Count_Return and @Count_Return = 0) OR (@Count_Arrive > @Count_Discharged and @Count_Discharged > 0) OR (@Count_Arrive > @Count_Ready and @Count_Ready > 0))
BEGIN
print 'recursing'
print @count_arrive
print @count_leave
print @count_prepped
print @count_return
print @count_discharged
print @count_ready
IF (@Count_Arrive > @Count_Leave and @Count_Leave > 0)
BEGIN
INSERT INTO
@Patient_Table
SELECT
@id,
'Patient Leave',
'No Data Provided'
SET @Count_Leave = @Count_Leave + 1
END
IF (@Count_Arrive > @Count_Prepped and @Count_Prepped > 0)
BEGIN
INSERT INTO
@Patient_Table
SELECT
@id,
'Patient Prepped',
'No Data Provided'
SET @Count_Prepped = @Count_Prepped + 1
END
IF (@Count_Arrive > @Count_Return and @Count_Return > 0)
BEGIN
INSERT INTO
@Patient_Table
SELECT
@id,
'Patient Return',
'No Data Provided'
SET @Count_Return = @Count_Return + 1
END
IF (@Count_Arrive > @Count_Discharged and @Count_Discharged > 0)
BEGIN
INSERT INTO
@Patient_Table
SELECT
@id,
'Patient Discharged',
'No Data Provided'
SET @Count_Discharged = @Count_Discharged + 1
END
IF (@Count_Arrive > @Count_Ready and @Count_Ready > 0)
BEGIN
INSERT INTO
@Patient_Table
SELECT
@id,
'Patient Ready',
'No Data Provided'
SET @Count_Ready = @Count_Ready + 1
END
END
FETCH NEXT FROM Patient_Cursor INTO @id
END
SELECT * FROM Patient_Table
SELECT * FROM @Patient_Table
答案 1 :(得分:0)
我不相信你需要一个光标(尽管使用它可能更有效)。我认为这可以满足您的需求。
WITH Pnumbered AS (
SELECT
P.ID, P.status, P.times, ROW_NUMBER() OVER (
PARTITION BY P.ID, P.status
ORDER BY P.times
) AS rn
FROM Patient_Table AS P
), PA AS (
SELECT
P.ID, P.status, P.times
FROM Patient_Table AS P
WHERE P.status = 'Patient Arrive'
), Enough AS (
SELECT PA.ID, S.status, S.statusseq, ROW_NUMBER() OVER (
PARTITION BY PA.ID, S.status
ORDER BY PA.times
) AS rn FROM PA
CROSS JOIN (
SELECT 'Patient Arrive',1 UNION ALL
SELECT 'Patient Prepped',2 UNION ALL
SELECT 'Patient Leave',3 UNION ALL
SELECT 'Patient Return',4 UNION ALL
SELECT 'Patient Ready',5 UNION ALL
SELECT 'Patient Discharged',6
) AS S(status,statusseq)
)
SELECT
Enough.ID, COALESCE(Pnumbered.status, Enough.status) as status, COALESCE(Pnumbered.times,'No Data Provided') AS times
FROM Pnumbered
RIGHT OUTER JOIN Enough
ON Pnumbered.ID = Enough.ID
AND Pnumbered.status = Enough.status
AND Pnumbered.rn = Enough.rn
ORDER BY ID, statusseq
这个想法如下:创建一个表格,每个患者ID
和每个status
复制的次数与ID
的“到达”行数相同,并对副本进行编号。同时按时间顺序对Patient_Data
表中具有相同(ID, status)
的行进行编号。最后,外连接这两个表,以便获得每个(ID,status)
的正确数量的副本,并用“未提供数据”替换外连接中不匹配行的NULL
。 (不匹配的行将是给定ID
和status
的行超过(ID,status)
表中Patient_Data
的实际行数。
如果您为Statuses
创建了S(status,statusseq)
表,则查询看起来会更简单。
这是输出:
ID status times
----------- ------------------ -------------------
123666 Patient Arrive 20180606 10:52
123666 Patient Arrive 20180606 11:21
123666 Patient Arrive 20180606 11:45
123666 Patient Prepped 20180606 10:52
123666 Patient Prepped 20180606 11:45
123666 Patient Prepped No Data Provided
123666 Patient Leave 20180606 10:52
123666 Patient Leave No Data Provided
123666 Patient Leave No Data Provided
123666 Patient Return No Data Provided
123666 Patient Return 20180606 10:55
123666 Patient Return 20180606 12:30
123666 Patient Ready 20180606 12:45
123666 Patient Ready No Data Provided
123666 Patient Ready No Data Provided
123666 Patient Discharged No Data Provided
123666 Patient Discharged No Data Provided
123666 Patient Discharged 20180606 12:45
123667 Patient Arrive 20180607 10:52
123667 Patient Prepped No Data Provided
123667 Patient Leave No Data Provided
123667 Patient Return No Data Provided
123667 Patient Ready No Data Provided
123667 Patient Discharged No Data Provided