如何使用动态 SQL 添加 2 列的值
How to use dynamic SQL to add value of 2 columns
我有一个小 table,其中包含学生的分数。 Table数据如下图所示。
在excel
中看起来像下面
我想使用动态 SQL 计算总数。我不想更新它。但是,我只想 select 使用动态 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
将 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 服务器不执行 "double headers",因此您无法在查询输出中获取 2018。您可以在 excel.
的第 1 行中手动添加“2018”的顶部 header
我有一个小 table,其中包含学生的分数。 Table数据如下图所示。
在excel
中看起来像下面我想使用动态 SQL 计算总数。我不想更新它。但是,我只想 select 使用动态 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
将 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 服务器不执行 "double headers",因此您无法在查询输出中获取 2018。您可以在 excel.
的第 1 行中手动添加“2018”的顶部 header