在SQL Server中将行转换为列

时间:2012-11-06 01:19:05

标签: sql sql-server pivot

我有一个返回以下结果集的查询:

patName  SName   DISC    SCHEDULE   
JM       AA      HA      2 per  Week
JM       MAC     MSW     1 per  Month
JM       ANG     RN      1 per  Week
JM       JON     RN      1 per  Week
JM       LRH     RN      1 per  Week

有什么方法可以使用PIVOT

按如下方式显示结果
PATNAME    HA           MSW             RN 
  JM    AA 2/Week   MAC 1/Month    ANG 1/week 
                                   JON 1/Week 
                                   LRH 1/Week

编辑,我的查询如下:

SELECT PatientName, [RN], [HA], [LVN], [MSW], [SC] 
  FROM 
  ( 
   SELECT DISTINCT (tblPatient.FirstName +' '+ tblPatient.LastName) As PatientName,
   (tblStaff.StaffFirstName+' '+tblStaff.StaffLastName) As StaffName, 
    (tblStaffDiscipline.Discipline)As Discipline, 
    CAST(tblFrequencyOfVisit.NoOfVisit As Varchar)+' per '
     + REPLACE (tblFrequencyOfVisit.Period,'/','') AS Visits new_value,
   row_number() over(partition by PatientName, Discipline order by Discipline) rowNum
   FROM tblPatient INNER JOIN
   tblFrequencyOfVisit 
   ON tblPatient.PatientId = tblFrequencyOfVisit.PatientId 
   INNER JOIN tblStaffAssignment 
   ON tblPatient.PatientId = tblStaffAssignment.PatientId 
   AND tblFrequencyOfVisit.PatientId = tblStaffAssignment.PatientId 
   INNER JOIN tblStaffDiscipline 
   ON tblFrequencyOfVisit.DisciplineId = tblStaffDiscipline.DisciplineId 
   INNER JOIN tblStaff 
   ON tblStaffAssignment.StaffId = tblStaff.StaffId 
   AND tblStaffDiscipline.Discipline = tblStaff.StaffDisciplane 
 )src  
 pivot
 (
  max(new_value)
  for Discipline in ([RN], [HA], [LVN], [MSW], [SC])
) piv

  WHERE
  tblpatient.PatientId = '138' 
  AND NOT tblPatient.SOC IS NULL 
  AND tblPatient.EOC IS NULL 
  AND tblPatient.Hospiceid = '1' 
  AND tblFrequencyofVisit.FromDate = 
   (Select MAX(FROMDATE) 
   From tblfrequencyofVisit 
   Where tblFrequencyOfVisit.PatientId = tblPatient.PatientId 
   AND tblFrequencyofVisit.Disciplineid = tblStaffDiscipline.Disciplineid )

1 个答案:

答案 0 :(得分:4)

您可以使用PIVOT功能执行此操作。如果您具有已知值,则可以使用静态数据透视表对列进行硬编码。为了使PIVOT中的分组正确,我添加了row_number(),因此结果将包括每条记录,而不仅仅是每max()的{​​{1}}值:

patname

请参阅SQL Fiddle with Demo

如果select patname, [HA], [MSW], [RN] from ( select patName, Disc, sname+' '+schedule new_value, row_number() over(partition by patname, disc order by disc) rowNum from <yourquery here> ) src pivot ( max(new_value) for disc in ([HA], [MSW], [RN]) ) piv 字段中有未知值,则可以使用动态SQL来转移数据:

DISC

请参阅SQL Fiddle with Demo

如果您没有可用的DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @cols = STUFF((SELECT distinct ',' + QUOTENAME(disc) from yourquery FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT patname, ' + @cols + ' from ( select patName, Disc, sname+'' ''+schedule new_value, row_number() over(partition by patname, disc order by disc) rowNum from <yourquery here> ) x pivot ( max(new_value) for Disc in (' + @cols + ') ) p ' exec(@query) 函数,则可以使用聚合函数和PIVOT语句复制此函数:

CASE

请参阅SQL Fiddle with Demo

编辑,根据您发布的查询,您可能需要使用以下内容:

select patname,
  max(case when disc='HA' then new_value end) HA,
  max(case when disc='MSW' then new_value end) MSW,
  max(case when disc='RN' then new_value end) RN,
  rowNum
from
(
  select patName, Disc,
    sname+' '+schedule new_value,
    row_number() over(partition by patname, disc order by disc) rowNum
  from yourquery
) src
group by patname, rownum