2017-10-16 78 views
2

有没有办法在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 

请指教(如有可能,带示例代码)。在此先感谢

回答

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) 
+0

谢谢@Martin,你的解决方案效果很好(虽然它对我来说很复杂:)) – Milacay

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 
+0

您需要将“FROM tblJob Where JobOwnerID = e.EmployeeID”添加到交叉应用中的每个查询中。 –

+0

@SeanLange - 不需要。许多人不知道这个语法实际上存在 –

+1

怎么可能不需要它。在原来的职位,他们需要从tblJob计数,而不是tblEmployee –

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; 
+1

这也是一个很好的解决方案。我尝试过,它完美。非常感谢@Amit – Milacay