如何使用T-Sql获取数据透视表类型数据

时间:2014-09-09 17:20:38

标签: sql sql-server sql-server-2008 tsql sql-server-2012

我得到了需要显示前3名员工的要求。它得到了显示前3名员工姓名的查询:

select top 3 [Employee First Name]+' '+[Employee Surname] as [Employee Full Name]  
from [Emp ]
group by [Employee First Name],[Employee Surname],[Annual Salary]
order by sum([Annual Salary]) desc

结果:

[EmpFullName]
---------------
Darren Ben
Sam nixon
Frances Oliv

但我想要的结果如下:

[FirstEmp]    [SecondEmp]   [ThirdEmp]
-------------------------------------------
Darren Ben    Sam nixon     Frances Oliv

我想要硬编码的列和名称。

感谢您的任何建议......

2 个答案:

答案 0 :(得分:1)

我发现这个解决方案有效,但不一定是最好的解决方案。 它基于向您的查询添加row_number列,然后使用COALESCE(MAX(选择3列。 (见SQL Server : Transpose rows to columns) 在这种情况下,在我看来比使用t-sql PIVOT更好。

SELECT 
COALESCE(MAX(CASE WHEN x = 1 THEN [Employee Full Name] END), 'n/a') as FirstEmp,
COALESCE(MAX(CASE WHEN x = 2 THEN [Employee Full Name] END), 'n/a') as SecondEmp,
COALESCE(MAX(CASE WHEN x = 3 THEN [Employee Full Name] END), 'n/a') as ThirdEmp
FROM (
    select top 3 
    row_number() over(order by [Annual Salary] desc) x,
    [Employee First Name]+' '+[Employee Surname] as [Employee Full Name]
    from Emp
    group by [Employee First Name],[Employee Surname],[Annual Salary]
    order by [Annual Salary] desc
    ) empRanks

我已将order by sum([Annual Salary]) desc替换为order by [Annual Salary] desc,因为内部SELECT已按[Annual Salary]分组。


脚本我习惯于填充数据来测试它:

DECLARE @emp TABLE
(
  [Employee First Name] varchar(50) NULL,
  [Employee Surname] varchar(50) NULL,
  [Annual Salary] int NULL
)

INSERT INTO @emp VALUES ('Darren','Ben',500)
INSERT INTO @emp VALUES ('Sam','nixon',600)
INSERT INTO @emp VALUES ('Frances','Oliv',700)
INSERT INTO @emp VALUES ('AAFrances','AAAOliv',200)
INSERT INTO @emp VALUES ('AAFrancsasaes','AAAOsasaliv',2000)

答案 1 :(得分:0)

也许有人可以简化这个:

create table #Emp (EmpId integer identity, [Employee First Name] varchar(30), [Employee Surname]  varchar(30), [Annual Salary] decimal)

insert into #Emp ([Employee First Name], [Employee Surname], [Annual Salary] )
values 
('Darren', 'Ben', 100000),
('Sam', 'Nixon', 80000),
('Frances', 'Oliv', 70000)


select * from (
select 
case (_order)
when 1 then 'FirstEmp'
when 2 then 'SecondEmp'
when 3 then 'ThirdEmp'
end as col
, q.name
from (
    select top 3 ROW_NUMBER() OVER ( ORDER BY [Annual Salary]  desc) as _order, [Employee First Name]+' '+[Employee Surname] as name
    from [#Emp ]
    group by EmpId, [Employee First Name],[Employee Surname],[Annual Salary]
    order by 1
) as q
) as o
pivot 
(
min(name)
for col in (FirstEmp, SecondEmp, ThirdEmp)
) as p 

使用ROW_NUMBER() OVER ...计算订单,然后PIVOT将行转置为列。

相关问题