我写了这个查询:
SELECT s, [1] AS a1, [2] AS a2, [3] AS a3, [4] AS a4
FROM (SELECT grade, aid, s FROM m) p
PIVOT
(
SUM(grade)
FOR aid IN ([1], [2], [3], [4])
) AS pvt ORDER BY pvt.s;
返回结果:
s a1 a2 a3 a4
1 25 69 95 56
2 27 99 16 87
. . . .
99 98 12 34 76
这正是我想要的结果。我的问题是“援助”中并不总是有四个不同的值。是否可以重写此查询(或使用存储过程),以便'a *'列的数量取决于'aid'中有多少个不同的值?
答案 0 :(得分:11)
您需要使用Dynamic Pivot来获取所需的列列表。这将首先检索列列表,然后转动该列表。类似的东西:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(aid)
FROM m
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT s, ' + @cols + ' from
(
select grade, aid, s
from m
) x
pivot
(
sum(grade)
for aid in (' + @cols + ')
) p
ORDER BY p.s'
execute(@query)
答案 1 :(得分:2)
Lamak:以下是我使用列别名的方法。别名链接到另一个表中由“aid”链接的列中的值。
DECLARE
@cols AS NVARCHAR(MAX),
@colsAlias AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(aid)
FROM m
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
SELECT @colsAlias = STUFF((SELECT DISTINCT ',' + QUOTENAME(m.aid) + ' AS ' + QUOTENAME(n.aName)
FROM m INNER JOIN n ON m.aid = n.aid
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @query = 'SELECT s, ' + @colsAlias + ' FROM
(
SELECT grade, aid, s
FROM m
) x
PIVOT
(
MIN(grade) FOR aid IN (' + @cols + ')
) p '
EXECUTE(@query)