将计数从水平转换为垂直

时间:2017-10-16 16:19:25

标签: tsql

有没有办法在SQL Server 2008中将结果从水平转换为垂直?

例如,我在下面有以下查询。

Select
(Select Count(*) FROM tblJob Where JobOwnerID = e.EmployeeID) AS JobTotal,
(Select Count(*) FROM tblJob Where JobOwnerID = e.EmployeeID and Status = 'Completed') AS JobTCompleted, 
(Select Count(*) FROM tblJob Where JobOwnerID = e.EmployeeID and Status = 'Expried') AS JobExpired
FROM tblEmployee e

然后该查询产生以下结果:

RecID   JobTotal    JobCompleted    JobExpired
1574    167         56              167
1621    216         85              215
1676    8           2               5

我想从该结果转换为垂直格式,如下例所示。

RecID   Category    FieldName       Value
1574    Job         JobTotal        167
1574    Job         JobCompleted    56
1574    Job         JobExpired      167
1621    Job         JobTotal        216
1621    Job         JobCompleted    85
1621    Job         JobExpired      215
1676    Job         JobTotal        8
1676    Job         JobCompleted    2
1676    Job         JobExpired      5

请告知(如果可能,请提供示例代码)。提前致谢

3 个答案:

答案 0 :(得分:2)

您可能会发现这样做效果更好,因为它可以避免重复聚合。

WITH J
     AS (SELECT JobOwnerID,
                COUNT(*)   AS JobTotal,
                COUNT(CASE
                        WHEN Status = 'Completed' THEN 1
                      END) AS JobTCompleted,
                COUNT(CASE
                        WHEN Status = 'Expried' THEN 1
                      END) AS JobExpired
         FROM   tblJob
         GROUP  BY JobOwnerID)
SELECT e.RecID,
       v.FieldName,
       ISNULL(Value, 0) AS Value
FROM   tblEmployee e
       LEFT JOIN J
              ON J.JobOwnerID = E.EmployeeID
       CROSS APPLY ( VALUES ('JobTotal', JobTotal),
                            ('JobCompleted', JobTCompleted),
                            ('JobExpired', JobExpired) ) V(FieldName, Value) 

答案 1 :(得分:1)

以下是使用Outer Apply

的一个技巧
SELECT RecID,
       Category,
       FieldName,
       Count(FieldName)
FROM   tblEmployee e
       Left join tblJob t on t.JobOwnerID = e.EmployeeID
       Outer apply (SELECT 'JobTCompleted' WHERE Status = 'Completed'
                    UNION ALL
                    SELECT 'JobExpired' WHERE Status = 'JobExpired'
                    UNION ALL
                    SELECT 'JobTotal') cs (FieldName) 
 Group By RecID,
       Category,
       FieldName

答案 2 :(得分:1)

您可以取消显示从原始查询中获得的结果数据集。

;WITH RESULT_TABLE AS
(Select e.RecID
(Select Count(*) FROM tblJob Where JobOwnerID = e.EmployeeID) AS JobTotal,
(Select Count(*) FROM tblJob Where JobOwnerID = e.EmployeeID and Status = 'Completed') AS JobTCompleted, 
(Select Count(*) FROM tblJob Where JobOwnerID = e.EmployeeID and Status = 'Expried') AS JobExpired
FROM tblEmployee e) 
SELECT RecID,[Option],[Value]
FROM
RESULT_TABLE  
UNPIVOT 
(
  [Value] FOR [Option] IN (JobTotal,JobCompleted,JobExpired)
) AS unpivotTable;