将 excel 屏幕截图作为预期输出,您只需指定感兴趣的 Year 即可完成此操作。
样本数据:
create table #sample_data
(
SNo int
, [LineNo] int
, ColumnNo int
, LineName varchar(15)
, ColumnName varchar(25)
, Marks int
, [Year] int
)
insert into #sample_data
values (1, 1, 1, 'Math', 'Jay', 97, 2018)
, (2, 1, 2, 'Math', 'Sam', 95, 2018)
, (3, 1, 3, 'Math', 'Jack', 90, 2018)
, (4, 2, 1, 'Science', 'Jay', 87, 2018)
, (5, 2, 2, 'Science', 'Sam', 88, 2018)
, (6, 2, 3, 'Science', 'Jack', 86, 2018)
, (7, 3, 1, 'Total', 'Jay', null, 2018)
, (8, 3, 2, 'Total', 'Sam', null, 2018)
, (9, 3, 3, 'Total', 'Jack', null, 2018)
答案:
下面的脚本根据Year 的设置确定相关的ColumnName 值,并根据ColumnNo 值强制列按预期顺序显示。透视适当的记录后,查询使用group by grouping sets 生成Total 记录。
declare @ColumnNameList nvarchar(max)
, @ColumnNameListSums nvarchar(max)
, @DynamicQuery nvarchar(max)
, @Year int = 2018 --set by OP in question
--get the full list of ColumnNames in a delimeter ("|") seperated string
set @ColumnNameList =
(
select stuff((
select '| ' + a.ColumnName
from (
select t.ColumnName
, min(t.ColumnNo) as ColumnNo
from #sample_data as t
where t.[Year] = @Year
group by t.ColumnName
) as a
order by a.ColumnNo
for xml path ('')
),1,1,'')
);
--its possible to use the previous variable as well, but easier to create another one
set @ColumnNameListSums =
(
select stuff((
select ', sum(a.' + a.ColumnName + ') as ' + a.ColumnName
from (
select t.ColumnName
, min(t.ColumnNo) as ColumnNo
from #sample_data as t
where t.[Year] = @Year
group by t.ColumnName
) as a
order by a.ColumnNo
for xml path ('')
),1,1,'')
);
set @DynamicQuery =
'
select isnull(b.LineName, ''Total'') as LineName
, b.' + ltrim(replace(@ColumnNameList, '| ', ', b.')) + '
from (
select a.LineName
, ' + @ColumnNameListSums + '
from (
select t.LineName
, t.ColumnName
, t.Marks
, t.[Year]
from #sample_data as t
where t.LineName <> (''Total'') --don''t need it, will generate totals later
and t.[Year] = ' + cast(@Year as char(4)) + '
) as a
pivot (max(a.Marks) for a.ColumnName in ([' + ltrim(replace(@ColumnNameList, '| ', '], [')) + '])) as a
group by grouping sets
(
(
a.LineName
)
,
(
--purposefully left empty
)
)
) as b
'
print @DynamicQuery --in order to see query being executed
exec(@DynamicQuery);
输出:
给定样本数据,生成以下输出。
+----------+-----+-----+------+
| LineName | Jay | Sam | Jack |
+----------+-----+-----+------+
| Math | 97 | 95 | 90 |
| Science | 87 | 88 | 86 |
| Total | 184 | 183 | 176 |
+----------+-----+-----+------+
SQL Server 不执行“双标头”,因此您无法在查询的输出中获得 2018。您可以在excel的第1行手动添加“2018”的顶部标题。