我有一张表,记录每次出勤的患者诊断。患者可以有多个诊断。
我希望每次出勤都有一排进行所有诊断(最多12次诊断)。下面会回来一行。
select
dg.AttendanceID
, dg.PatientNumber
, dg.DiagnosisDate
, dg.Diagnosis
from
Diagnosis dg
AttendanceID PatientNumber DiagnosisDate Diagnosis
10001 123456 01-Oct-13 A
10001 123456 01-Oct-13 B
10002 123456 20-Oct-13 D
结果应如下所示:
AttendanceID PatientNumber DiagnosisDate Diagnosis 1 Diagnosis 2 Diagnosis 3
10001 123456 01-Oct-13 A B
10002 123456 20-Oct-13 D
有人可以帮忙吗?
答案 0 :(得分:2)
您可以通过实施PIVOT功能获得结果,但我还建议使用窗口函数row_number()
来生成每个attendanceid
和patientnumber
的诊断数量:
select attendanceid, patientnumber,
diagnosisdate,
Diagnosis1, Diagnosis2, Diagnosis3
from
(
select attendanceid, patientnumber,
diagnosisdate, diagnosis,
'diagnosis'+
cast(row_number() over(partition by attendanceid, patientnumber
order by diagnosis) as varchar(2)) seq
from diagnosis
) d
pivot
(
max(diagnosis)
for seq in (Diagnosis1, Diagnosis2, Diagnosis3)
) piv;
见SQL Fiddle with Demo。由于您知道每位患者/出勤者最多可以进行12次诊断,因此您可以轻松地对查询进行硬编码以添加其他列。
但是如果您需要动态版本的代码,那么您可以使用类似于以下内容的内容:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(seq)
from
(
select 'diagnosis'+
cast(row_number() over(partition by attendanceid, patientnumber
order by diagnosis) as varchar(2)) seq
from diagnosis
) d
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT attendanceid, patientnumber,
diagnosisdate,' + @cols + '
from
(
select attendanceid, patientnumber,
diagnosisdate, diagnosis,
''diagnosis''+
cast(row_number() over(partition by attendanceid, patientnumber
order by diagnosis) as varchar(2)) seq
from diagnosis
) x
pivot
(
max(diagnosis)
for seq in (' + @cols + ')
) p '
execute sp_executesql @query;
两个版本都给出了结果:
| ATTENDANCEID | PATIENTNUMBER | DIAGNOSISDATE | DIAGNOSIS1 | DIAGNOSIS2 | DIAGNOSIS3 |
|--------------|---------------|--------------------------------|------------|------------|------------|
| 10001 | 123456 | October, 01 2013 00:00:00+0000 | A | B | (null) |
| 10002 | 123456 | October, 20 2013 00:00:00+0000 | D | (null) | (null) |
答案 1 :(得分:0)
我不是百分百肯定,但它应该是这样的。
;with cte as(
select
dg.AttendanceID
, dg.PatientNumber
, dg.DiagnosisDate
, dg.Diagnosis
,ROW_NUMBER() over (partition by dg.attendanceID order by attendanceID) as seq1
,ROW_NUMBER() over (partition by dg.attendanceID, patient_no order by diagnosis) as seq2
from
Diagnosis dg
)
select
t1.attendanceID
,t1.patientNumber
,t1.diagnosisDate
,(select Diagnosis from cte t2 where t1.attendanceID=t2.attendanceID and t1.patientNumber=t2.patientNumber and t2.seq2='1') as diag1
,(select Diagnosis from cte t2 where t1.attendanceID=t2.attendanceID and t1.patientNumber=t2.patientNumber and t2.seq2='2') as diag2
,(select Diagnosis from cte t2 where t1.attendanceID=t2.attendanceID and t1.patientNumber=t2.patientNumber and t2.seq2='3') as diag3
,(select Diagnosis from cte t2 where t1.attendanceID=t2.attendanceID and t1.patientNumber=t2.patientNumber and t2.seq2='4') as diag4
,(select Diagnosis from cte t2 where t1.attendanceID=t2.attendanceID and t1.patientNumber=t2.patientNumber and t2.seq2='5') as diag5
from cte t1
where seq1= 1
答案 2 :(得分:0)
以下是使用游标的可能解决方案我不确定您是否可以将其显示为列,因为它对于每个患者都是可变的但是这将在单个列中显示为逗号分隔的诊断
DECLARE @combinedString VARCHAR(MAX),
@id int,
@Diagnosis VARCHAR(MAX)
Declare @CONCATRESULT TABLE (AttendanceID int, Question VARCHAR(MAX) )
Declare Dia cursor for
SELECT AttendanceID FROM Diagnosis
open Dia
Fetch next from Dia into @id
while @@FETCH_STATUS=0
begin
SELECT @combinedString = COALESCE(@combinedString + ', ', '') + Diagnosis,
@id=AttendanceID FROM [Prod_PostData].[dbo].[KMSFPostDataDenorm] d
WHERE AttendanceID = @id
insert into @CONCATRESULT values ( @id ,@combinedString )
SET @combinedString = null
Fetch next from Dia into @id
end
close Dia
deallocate Dia
select
dg.AttendanceID
, dg.PatientNumber
, dg.DiagnosisDate
, dg.Diagnosis
from
Diagnosis dg join (select * from @CONCATRESULT) Y on dg.AttendanceID=Y.AttendanceID