替代构建大型数据透视查询

时间:2013-08-27 14:52:44

标签: sql tsql pivot

我有2个表我从报告中获取数据(我在本例中使用通用表):

CREATE TABLE Department
(
DeptId int NOT NULL PRIMARY KEY IDENTITY(1,1),
DepartmentName varchar(20) NOT NULL
)


CREATE TABLE Employee
(
EmpId int NOT NULL PRIMARY KEY IDENTITY(1,1),
FirstName varchar(20) NULL,
LastName varchar(30) NULL,
WorkStatus int NOT NULL,
DeptId int NOT NULL
 )


INSERT INTO Department (DepartmentName)
Values ('Finance'),
       ('Personnel'),
       ('Research'),
       ('Info Tech'),
       ('Production')

INSERT INTO Employee (FirstName, LastName, WorkStatus, DeptId)
VALUES  ('Steve', 'Smith', 2, 3),
    ('Jim', 'Jones', 3, 1),
    ('Dave', 'Black', 1, 2),
    ('Nancy', 'White', 2, 4),
    ('Judith', 'North', 1, 5),
    ('Austin', 'West', 3, 5),
    ('Herbert', 'Livingston', 2, 5)

我需要创建一个报告,按部门列出不同工作状态的数量,因此研究中有一个人有工作状态2,依此类推。我通常会使用数据透视查询,例如:

    SELECT DepartmentName, [1] as [Status 1],[2] as [Status 2],[3] as [Status 3]  FROM
    (SELECT    e.EmpId, d.DepartmentName, e.WorkStatus as WkStatus
          FROM  dbo.Employee e
                      INNER JOIN dbo.Department d
                            ON e.DeptId = D.DeptId
          WHERE d.DeptId = 1

          UNION

     SELECT    e.EmpId, d.DepartmentName, e.WorkStatus as WkStatus
          FROM  dbo.Employee e
                      INNER JOIN dbo.Department d
                            ON e.DeptId = D.DeptId
          WHERE d.DeptId = 2

          UNION

    SELECT    e.EmpId, d.DepartmentName, e.WorkStatus as WkStatus
          FROM  dbo.Employee e
                      INNER JOIN dbo.Department d
                            ON e.DeptId = D.DeptId
          WHERE d.DeptId = 3
          UNION

    SELECT    e.EmpId, d.DepartmentName, e.WorkStatus as WkStatus
          FROM  dbo.Employee e
                      INNER JOIN dbo.Department d
                            ON e.DeptId = D.DeptId
          WHERE d.DeptId = 4

          UNION

    SELECT    e.EmpId, d.DepartmentName, e.WorkStatus as WkStatus
          FROM  dbo.Employee e
                      INNER JOIN dbo.Department d
                            ON e.DeptId = D.DeptId
          WHERE d.DeptId = 5
                ) UNIONqry
    PIVOT
    (count(EmpId) for WkStatus in ([1],[2],[3])) pvt
    Order by DepartmentName

但是我正在寻找一个更好的方法,因为我正在构建的实际查询有120个部门'这将意味着120个工会。我做的最后一件事只有18个部门'并且查询需要2秒才能运行,因此我假设120将需要一些时间。所以我想知道是否有更好的方法可以解决这个问题,或者我是否应该继续使用上面提供的联合支持'方法

2 个答案:

答案 0 :(得分:2)

如果您想要计算每个部门的工作状态,那么您应该能够使用PIVOT并且不能使用UNIONs:

select departmentname,
  [1] status1,
  [2] status2,
  [3] status3
from
(
  select d.departmentname, e.empid, e.workstatus
  from dbo.department d
  left join dbo.employee e
    on d.deptid = e.deptid
) d
pivot
(
  count(empid)
  for workstatus in ([1],[2],[3])
) piv;

SQL Fiddle with Demo。我更改了JOIN以使用LEFT JOIN,即使dbo.employees表中没有匹配的值,也会返回所有部门。

答案 1 :(得分:1)

您只想要条件聚合吗?

SELECT d.DepartmentName,
       sum(case when e.WorkStatus = 1 then 1 else 0 end) as [1],
       sum(case when e.WorkStatus = 2 then 1 else 0 end) as [2],
       sum(case when e.WorkStatus = 3 then 1 else 0 end) as [3]
FROM  dbo.Employee e INNER JOIN
      dbo.Department d
      ON e.DeptId = D.DeptId
group by d.DepartmentName;

您不在问题中包含示例结果,但我认为这是您要做的事情。您可以为不同的工作状态添加更多sum(case . . . )子句。