数据透视函数 returns 只有总计
Pivot function returns only grand total
我正在尝试了解 pivot table 的工作原理。
IF OBJECT_ID(N'tempdb..#exams') IS NOT NULL
BEGIN
DROP TABLE #exams
END
GO
create table #exams (
id uniqueidentifier,
exam nvarchar(max),
technician nvarchar(max)
)
insert into #exams
values
(newid(),'Esame1','Tecnico1'),
(newid(),'Esame2','Tecnico1'),
(newid(),'Esame1','Tecnico2'),
(newid(),'Esame3','Tecnico1'),
(newid(),'Esame3','Tecnico2'),
(newid(),'Esame3','Tecnico3'),
(newid(),'Esame3','Tecnico1')
我知道如何使用 sum case 来得到我要找的东西:
select
exam,
sum(case when technician = 'Tecnico1' then 1 else 0 end) as Tecnico1,
sum(case when technician = 'Tecnico2' then 1 else 0 end) as Tecnico2,
sum(case when technician = 'Tecnico3' then 1 else 0 end) as Tecnico3
from #exams
group by exam
order by exam
exam Tecnico1 Tecnico2 Tecnico3
Esame1 1 1 0
Esame2 1 0 0
Esame3 2 1 1
顺便说一句,我有很多技术人员,我想使用动态列自动执行查询。
当我尝试数据透视语法时
select * from (
select exam,
technician
from #exams
) as t
pivot
( count(exam)
for technician in (Tecnico1,Tecnico2,Tecnico3)
) as t
我只得到总计
Tecnico1 Tecnico2 Tecnico3
4 2 1
如何获得和式语法的相同结果?
您必须在子查询中包含 id:
select * from (
select id,exam,
technician
from #exams
) as t
pivot
( count(id)
for technician in (Tecnico1,Tecnico2,Tecnico3)
) as t
动态:
DECLARE @sql nvarchar(max);
DECLARE @columnname nvarchar(max);
SELECT @columnname=COALESCE(@columnname+ ',', '') + QUOTENAME(CAST(q.technician AS nvarchar(20)),'[]')
FROM
(SELECT DISTINCT e.technician
FROM #exams e) AS q
SET @sql=
'select * from (
select id,exam,
technician
from #exams
) as t
pivot
( count(id)
for technician in ('+@columnname+')
) as t'
EXECUTE sp_executesql @sql
pivot
语法不支持将值列表作为子查询传递。这是 SQL 中的典型限制:查询必须 return 一组 固定的 列。
您要求的内容需要动态 SQL。在 SQL 服务器中,它看起来像:
declare @sql as nvarchar(max);
select @sql =
'select exam, '
+ string_agg(
'sum(case when technician = ''' + technician + ''' then 1 else 0 end) as [' + technician + ']',
', '
)
+ ' from #exams group by exam'
from #exams;
execute(@sql);
我正在尝试了解 pivot table 的工作原理。
IF OBJECT_ID(N'tempdb..#exams') IS NOT NULL
BEGIN
DROP TABLE #exams
END
GO
create table #exams (
id uniqueidentifier,
exam nvarchar(max),
technician nvarchar(max)
)
insert into #exams
values
(newid(),'Esame1','Tecnico1'),
(newid(),'Esame2','Tecnico1'),
(newid(),'Esame1','Tecnico2'),
(newid(),'Esame3','Tecnico1'),
(newid(),'Esame3','Tecnico2'),
(newid(),'Esame3','Tecnico3'),
(newid(),'Esame3','Tecnico1')
我知道如何使用 sum case 来得到我要找的东西:
select
exam,
sum(case when technician = 'Tecnico1' then 1 else 0 end) as Tecnico1,
sum(case when technician = 'Tecnico2' then 1 else 0 end) as Tecnico2,
sum(case when technician = 'Tecnico3' then 1 else 0 end) as Tecnico3
from #exams
group by exam
order by exam
exam Tecnico1 Tecnico2 Tecnico3
Esame1 1 1 0
Esame2 1 0 0
Esame3 2 1 1
顺便说一句,我有很多技术人员,我想使用动态列自动执行查询。
当我尝试数据透视语法时
select * from (
select exam,
technician
from #exams
) as t
pivot
( count(exam)
for technician in (Tecnico1,Tecnico2,Tecnico3)
) as t
我只得到总计
Tecnico1 Tecnico2 Tecnico3
4 2 1
如何获得和式语法的相同结果?
您必须在子查询中包含 id:
select * from (
select id,exam,
technician
from #exams
) as t
pivot
( count(id)
for technician in (Tecnico1,Tecnico2,Tecnico3)
) as t
动态:
DECLARE @sql nvarchar(max);
DECLARE @columnname nvarchar(max);
SELECT @columnname=COALESCE(@columnname+ ',', '') + QUOTENAME(CAST(q.technician AS nvarchar(20)),'[]')
FROM
(SELECT DISTINCT e.technician
FROM #exams e) AS q
SET @sql=
'select * from (
select id,exam,
technician
from #exams
) as t
pivot
( count(id)
for technician in ('+@columnname+')
) as t'
EXECUTE sp_executesql @sql
pivot
语法不支持将值列表作为子查询传递。这是 SQL 中的典型限制:查询必须 return 一组 固定的 列。
您要求的内容需要动态 SQL。在 SQL 服务器中,它看起来像:
declare @sql as nvarchar(max);
select @sql =
'select exam, '
+ string_agg(
'sum(case when technician = ''' + technician + ''' then 1 else 0 end) as [' + technician + ']',
', '
)
+ ' from #exams group by exam'
from #exams;
execute(@sql);