2013-11-26 25 views
1

我有一张记录每位出勤病人诊断的表格。患者可以有多个诊断。SQL一对多一对一

我希望所有诊断都有一行出席(最多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

我相信PIVOT可以在这里完成这项工作吗? – NickyvV

回答

0

我不是100%确定,但它应该是沿着这些线。

;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 
+0

你不觉得你需要群组吗? – DevelopmentIsMyPassion

+0

这可行,但我不明白复杂的语法。谢谢, – user3036111

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 
2

您可以通过实现旋转功能得到的结果,但我也建议使用窗口函数row_number()生成诊断为每个​​attendanceidpatientnumber数量:

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; 

SQL Fiddle with Demo

两个版本给出一个结果:

| 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) |