问题
I have a table that contains procedure data. There can be up to 49 entries for a given encounter. I want to output one row for each account and include the procedure, date and provider. I've tried writing CASE statements to this end:
Select DISTINCT [Encounter Number],
CASE When [Encounter Proc Sequence] = '1' Then [Procedure Code (Enctr)]
END as 'Proc1',
Case When [Encounter Proc Sequence] = '1' Then [Date of Service]
END as 'SvcDate1',
CASE When [Encounter Proc Sequence] = '1' Then [Surgeon]
END as 'Surgeon1',
CASE When [Encounter Proc Sequence] = '2' Then [Procedure Code (Enctr)]
END as 'Proc2',
Case When [Encounter Proc Sequence] = '2' Then [Date of Service]
END as 'SvcDate2',
CASE When [Encounter Proc Sequence] = '2' Then [Surgeon]
END as 'Surgeon2',
CASE When [Encounter Proc Sequence] = '3' Then [Procedure Code (Enctr)]
END as 'Proc3',
Case When [Encounter Proc Sequence] = '3' Then [Date of Service]
END as 'SvcDate3',
CASE When [Encounter Proc Sequence] = '3' Then [Surgeon]
END as 'Surgeon3',
CASE When [Encounter Proc Sequence] = '4' Then [Procedure Code (Enctr)]
END as 'Proc4',
Case When [Encounter Proc Sequence] = '4' Then [Date of Service]
END as 'SvcDate4',
CASE When [Encounter Proc Sequence] = '4' Then [Surgeon]
END as 'Surgeon4',
CASE When [Encounter Proc Sequence] = '5' Then [Procedure Code (Enctr)]
END as 'Proc5',
Case When [Encounter Proc Sequence] = '5' Then [Date of Service]
END as 'SvcDate5',
CASE When [Encounter Proc Sequence] = '5' Then [Surgeon]
END as 'Surgeon5',
CASE When [Encounter Proc Sequence] = '6' Then [Procedure Code (Enctr)]
END as 'Proc6',
Case When [Encounter Proc Sequence] = '6' Then [Date of Service]
END as 'SvcDate6',
CASE When [Encounter Proc Sequence] = '6' Then [Surgeon]
END as 'Surgeon6',
CASE When [Encounter Proc Sequence] = '7' Then [Procedure Code (Enctr)]
END as 'Proc7',
Case When [Encounter Proc Sequence] = '7' Then [Date of Service]
END as 'SvcDate7',
CASE When [Encounter Proc Sequence] = '7' Then [Surgeon]
END as 'Surgeon7'
from EncounterProc
where [Date of Service] between '20090101' and '20091231'
and [Procedure Code (ENCTR)] is not null
Group by [Encounter Number], [Encounter Proc Sequence],[Procedure Code (ENCTR)], [Date of
Service], Surgeon
The query output shows some duplicated rows and the query isn't placing procedure 3 (for example) in the Proc3 column.
How would I setup the PIVOT syntax for this scenario?
UPDATE: I've read the MSDN Library documentation on PIVOT, and also the link shared in Comments. I took a stab at adapting those sources to my need as follows:
Select [Encounter Number],
[1] as Proc1,
[Date1] as SvcDate1,
[MD1] as MD1,
[2] as Proc2,
[Date2] as SvcDate2,
[MD2] as MD2,
[3] as Proc3,
[Date3] as SvcDate3,
[MD3] as MD3,
[4] as Proc4,
[Date4] as SvcDate4,
[MD4] as MD4
From
(Select * From
(SELECT [Encounter Number]
,[Procedure Code (Enctr)]
,Row_Number() OVER ( Partition By [Encounter Number] Order By
[Encounter Number], [Procedure Code (Enctr)] ) AS RowNumber
FROM EncounterProc)
PIVOT ( MAX([Procedure Code (Enctr)] ) for RowNumber IN
( [1], [Date1], [MD1],[2], [Date2], [MD2], [3], [Date3], [MD3], [4], [Date4],
[MD4]))
When I run this query, SSMS gives me the following error:
Incorrect syntax near the keyword 'PIVOT'.
Update2: Based on Stuart's comment, I've revised the query to be:
Select [Encounter Number],
p.[1] as Proc1,
p.[Date1] as SvcDate1,
p.[MD1] as MD1,
p.[2] as Proc2,
p.[Date2] as SvcDate2,
p.[MD2] as MD2,
p.[3] as Proc3,
p.[Date3] as SvcDate3,
p.[MD3] as MD3,
p.[4] as Proc4,
p.[Date4] as SvcDate4,
p.[MD4] as MD4
From
(Select * From
(SELECT [Encounter Number]
,[Procedure Code (Enctr)]
,[Date of Service]
,[Surgeon]
,Row_Number() OVER ( Partition By [Encounter Number] Order By
[Encounter Number], [Encounter Proc Sequence] ) AS RowNumber
FROM EncounterProc) p
PIVOT ( MAX([Procedure Code (Enctr)] ) for RowNumber IN
( [1], [Date1], [MD1],[2], [Date2], [MD2], [3], [Date3], [MD3], [4], [Date4],
[MD4]) )
I now receive a new error stating:
Msg 102, Level 15, State 1, Line 23
Incorrect syntax near ')'.
which points to the closing parenthesis of the PIVOT statement.
What must be done to fix the syntax error?
回答1:
Your first query is the closest one, except that you did not enclosed every case into aggreagate function. Also it seems that you do not need some columns in group by clause:
select
[Encounter Number],
Proc1 = max(CASE When [Encounter Proc Sequence] = '1' Then [Procedure Code (Enctr)] END),
SvcDate1 = max(Case When [Encounter Proc Sequence] = '1' Then [Date of Service] END),
Surgeon1 = max(CASE When [Encounter Proc Sequence] = '1' Then [Surgeon] END),
Proc2 = max(CASE When [Encounter Proc Sequence] = '2' Then [Procedure Code (Enctr)] END),
SvcDate2 = max(Case When [Encounter Proc Sequence] = '2' Then [Date of Service] END),
Surgeon2 = max(CASE When [Encounter Proc Sequence] = '2' Then [Surgeon] END),
Proc3 = max(CASE When [Encounter Proc Sequence] = '3' Then [Procedure Code (Enctr)] END),
SvcDate3 = max(Case When [Encounter Proc Sequence] = '3' Then [Date of Service] END),
Surgeon3 = max(CASE When [Encounter Proc Sequence] = '3' Then [Surgeon] END)
--- etc.
from EncounterProc
where [Date of Service] between '20090101' and '20091231'
and [Procedure Code (ENCTR)] is not null
group by [Encounter Number], [Encounter Proc Sequence]
来源:https://stackoverflow.com/questions/18282722/how-to-pivot-over-up-to-49-fields