在Sql中将行数转换为列格式

时间:2015-01-15 06:57:23

标签: sql-server tsql

我有下表:

VID RS
1   A
1   B
1   B
2   C
2   A

我想要做的是计算每个VID的每个RS的计数,并希望得到如下输出:

VID A   B   C
1   1   2   0
2   1   0   1

是否可以通过查询或我需要创建临时表并执行插入/更新? 感谢

4 个答案:

答案 0 :(得分:2)

如果RS的号码已修复,则可以

select vid, 
       sum(case when RS = 'A' then 1 else 0 end) AS A,
       sum(case when RS = 'B' then 1 else 0 end) AS B,
       sum(case when RS = 'C' then 1 else 0 end) AS C
from your_table
group by vid

答案 1 :(得分:2)

你可以用两种方式做到这一点

一个是使用Pivot

SELECT *
FROM   Yourtable
       PIVOT (Count(rs)
             FOR rs IN([A],
                       [B],
                       [C]) )piv

注意: 如果您的RS列值不是static,请将数据透视转换为Dynamic Pivot

另一种方法是使用Conditional Aggregate

SELECT vid,
       Count(CASE Rs WHEN 'A' THEN 1 END) [A],
       Count(CASE Rs WHEN 'B' THEN 1 END) [B],
       Count(CASE Rs WHEN 'C' THEN 1 END) [C]
FROM   Yourtable
GROUP  BY vid 

SQLFIDDLE DEMO

答案 2 :(得分:1)

查看msdn上的pivot命令,它将执行此操作。

更新

对于这个例子:

SELECT Vid,
       [A] AS 'A',
       [B] AS 'B',
       [C] AS 'C'
FROM   your_table
       PIVOT (Count(RS)
             FOR RS IN( [A],
                        [B],
                        [C])) AS PivotTable; 

答案 3 :(得分:0)

如果RS中的值是动态的,则应选择dynamic pivot

样本表

SELECT * INTO #TEMP
FROM
(
    SELECT 1 VID,   'A' RS
    UNION ALL
    SELECT 1,   'B'
    UNION ALL
    SELECT 1,   'B'
    UNION ALL
    SELECT 2,   'C'
    UNION ALL
    SELECT 2,   'A'
)TAB

<强> QUERY

声明两个变量以获取pivot的列,并将NULL替换为零

DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + RS + ']','[' + RS + ']')
               FROM    (SELECT DISTINCT RS FROM #TEMP) PV  
               ORDER BY RS

DECLARE @NullToZeroCols NVARCHAR (MAX)
SET @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+RS+'],0) AS ['+RS+']' 
FROM(SELECT DISTINCT RS FROM #TEMP GROUP BY RS)TAB  
ORDER BY RS  FOR XML PATH('')),2,8000)  

现在进行计数和转动

DECLARE @query NVARCHAR(MAX)
SET @query = '
             SELECT VID,' + @NullToZeroCols + ' FROM 
             (
                 SELECT VID,RS,COUNT(RS)OVER(PARTITION BY VID,RS)CNT
                 FROM #TEMP
             ) x
             PIVOT 
             (
                 MIN(CNT)
                 FOR RS IN (' + @cols + ')
            ) p;' 

EXEC SP_EXECUTESQL @query