SQL Server 2008 R2 Pivot问题

时间:2013-06-03 09:01:49

标签: sql sql-server tsql sql-server-2008-r2 pivot

我在这里显示Table1

;WITH Table1 AS (
SELECT *
FROM (VALUES 
(164021, 'Balajee', 100, 100, 'YTD'),
(164021, 'Balajee', 200, 100, 'YTD'),
(164021, 'Balajee', 400, 300, 'MTD'),
(164021, 'Balajee', 200, 100, 'MTD')
) as t (EmpID, [Emp Name], GROSS_PAY, NET_PAY, DUR_TYPE)
)

此表包含称为持续时间类型的列,其值可以为YTDMTD。现在,在使用Pivot进行选择后,我想要我的表,看起来像下表中显示的那样。有人可以帮我这么做吗?我对这个Pivot很新,需要一些帮助。

EmpID   Empname Grosspay_ytd    net_pay_ytd Grosspay_mtd    netpay_mtd
------- ------- --------------- ----------- --------------- -----------
164021  Balajee 300             200         600             400

2 个答案:

答案 0 :(得分:2)

您可以使用PIVOT函数来获取结果,但问题的一部分是您要在两列中转动两列。

由于要转移的数据分为两列,因此有几种方法可以获得结果。您可以将聚合函数与CASE表达式一起使用:

select empid, empname,
  sum(case when dur_type='YTD' then gross_pay else 0 end) gross_pay_ytd,
  sum(case when dur_type='YTD' then net_pay else 0 end) net_pay_ytd,
  sum(case when dur_type='MTD' then gross_pay else 0 end) gross_pay_mtd,
  sum(case when dur_type='MTD' then net_pay else 0 end) net_pay_mtd
from yt
group by empid, empname;

请参阅SQL Fiddle with Demo

如果要使用PIVOT功能,则可以取消gross_paynet_pay列中的数据,以便数据存在于一列中,然后应用PIVOT功能。由于您使用的是SQL Server 2008,因此您可以使用带有VALUES子句的CROSS APPLY对数据进行取消操作:

select empid, empname, col+'_'+dur_type as col, value
from yt
cross apply 
(
  values
    ('gross_pay', gross_pay), ('net_pay', net_pay)
) c (col, value)

Demo。这会将当前数据转换为结果:

|  EMPID | EMPNAME |           COL | VALUE |
--------------------------------------------
| 164021 | Balajee | gross_pay_YTD |   100 |
| 164021 | Balajee |   net_pay_YTD |   100 |
| 164021 | Balajee | gross_pay_YTD |   200 |
| 164021 | Balajee |   net_pay_YTD |   100 |

正如您所看到的,我们知道每个员工都有多行,其中包含一列 最终数据结果中所需列的名称。当您应用PIVOT功能时,代码将是:

select empid, empname,
  gross_pay_ytd, net_pay_ytd, gross_pay_mtd, net_pay_mtd
from
(
  select empid, empname, col+'_'+dur_type as col, value
  from yt
  cross apply 
  (
    values
      ('gross_pay', gross_pay), ('net_pay', net_pay)
  ) c (col, value)
) d
pivot
(
  sum(value)
  for col in (gross_pay_ytd, net_pay_ytd, gross_pay_mtd, net_pay_mtd)
) piv;

SQL Fiddle with Demo。此版本和CASE版本都会给出结果:

|  EMPID | EMPNAME | GROSS_PAY_YTD | NET_PAY_YTD | GROSS_PAY_MTD | NET_PAY_MTD |
--------------------------------------------------------------------------------
| 164021 | Balajee |           300 |         200 |           600 |         400 |

答案 1 :(得分:1)

试试这个sql。

select empid,empname,sum(case dur_type when dur_type='YTD' then gross_pay else 0 END)as grosspay_ytd,
sum(case when dur_type='MTD' then gross_pay else 0 END) as grosspay_mtd  ,
sum(case when dur_type='YTD' then net_pay else 0 END) as netpay_ytd,
sum(case when dur_type='MTD' then net_pay else 0 END) as netpay_mtd
from employee
group by empid,empname,dur_type