我有一张包含学生标记的小桌子。表格数据如下图所示。
在excel中看起来像下面
我想用动态SQL计算总数。我不想更新它。但是,我只想使用动态SQL选择计算总数的所有数据。
请参考以下代码:
DECLARE @SQL NVARCHAR(MAX)=''
DECLARE @SNumberList NVARCHAR(MAX)=''
DECLARE @CalculatedLineNumbers NVARCHAR(MAX)=''
SELECT @CalculatedLineNumbers = @CalculatedLineNumbers+ ', '+
CASE WHEN SNo = 7 THEN '[1] + [4] [7]'
WHEN SNo = 8 THEN '[2] + [5] [8]'
WHEN SNo = 9 THEN '[3] + [6] [7]'
ELSE QUOTENAME(SNo)
END
FROM Student
SELECT @SNumberList = @SNumberList+ ', '+QUOTENAME(SNo)
FROM Student
SELECT @SNumberList=STUFF(@SNumberList, 1,1, ''),
@CalculatedLineNumbers=STUFF(@CalculatedLineNumbers,1,1,'')
SET @SQL= '
SELECT Year,'+@CalculatedLineNumbers+'
FROM
(
SELECT *
from Student s) AS J
PIVOT
(
MAX([Marks]) FOR Marks IN ('+@SNumberList+')
) AS P'
EXEC SP_EXECUTESQL @SQL
答案 0 :(得分:1)
将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)
<强>答案:强>
下面的脚本根据设置ColumnName
确定相关的Year
值,并根据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”的顶部标题。