如何动态获取 table 中多行的总和
How to get sum of multiple rows in a table dynamically
我正在尝试从数据库中多个 table 的特定数据类型(金钱)的列中获取总和。目前我能够从特定的 table 中获取列列表,但我无法从这些列中获取总和。
这就是我现在拥有的
use database 1
Select + Column_Name
From information_schema.columns
Where TABLE_NAME = 'claimant'
and data_type = 'money'
结果如下所示
table_name
column_name
table_1
column_a
table_1
column_b
table_1
column_c
我想要什么
table_name
column_name
total_sum
table_1
column_a
66.20
table_1
column_b
300.50
table_1
column_c
5389.42
@Squirrel 的更新这是我的代码,但它仍然给我带来截断问题。
{
declare @sql nvarchar(max);
select @sql = 'with cte as (' + char(13)
+ 'select' + char(13)
+ string_agg(char(9) + quotename(column_name) + ' = sum(' + quotename(COLUMN_NAME) + ')', ',' + char(13)) + char(13)
+ 'from ' + max(quotename(table_name)) + char(13)
+ ')' + char(13)
+ 'select a.table_name, a.column_name, a.total_sum ' + char(13)
+ 'from cte ' + char(13)
+ 'cross apply (' + char(13)
+ char(9) + 'values' + char(13)
+ string_agg(char(9) + '(''' + table_name + ''',''' + column_name + ''',' + quotename(COLUMN_NAME) + ')', ',' + char(13)) + char(13)
+ ') a (table_name, column_name, total_sum)'
from information_schema.columns AS A
INNER JOIN EDL01.STAGING.TABLE_DETAILS B
ON A.TABLE_NAME = B.DEST_TABLE_NAME
where A.table_name = B.DEST_TABLE_NAME
and data_type = 'money'
print @sql
exec sp_executesql @sql
}
下面是创建table
CREATE TABLE [staging].[TABLE_DETAILS](
[SOURCE_TABLE_NAME] [varchar](100) NULL,
[DEST_TABLE_NAME] [varchar](100) NULL,
[TYPE] [varchar](10) NULL,
[PRIORITY] [int] NULL,
[SOURCE_TABLE_DATABASE] [varchar](50) NULL,
[SOURCE_TABLE_SCHEMA] [varchar](50) NULL,
[DEST_TABLE_DATABASE] [varchar](50) NULL,
[DEST_TABLE_SCHEMA] [varchar](50) NULL
) ON [PRIMARY]
GO
以下是部分结果
select a.table_name, a.column_name, a.total_sum
from cte
cross apply (
values
('PAYMENT','BILLEDAMOUNT',[BILLEDAMOUNT]),
('PAYMENT','AMOUNT',[AMOUNT]),
('SIMS_PAYMENT','CHECKAMOUNT',[CHECKAMOUNT]),
('BILLREVIEWHEADER','JURISDICTIONAMOUNT1',[JURISDICTIONAMOUNT1]),
('BILLREVIEWHEADER','JURISDICTIONAMOUNT2',[JURISDICTIONAMOUNT2]),
('BILLREVIE
您需要动态形成查询,然后使用 sp_executesql
或 exec()
执行它
注意:char(9)
是制表符,char(13)
是回车符return。添加这些是为了格式化查询,以便在您 print
进行验证时它是可读的。
declare @sql nvarchar(max);
select @sql = 'with cte as (' + char(13)
+ 'select' + char(13)
+ string_agg(char(9) + quotename(column_name) + ' = sum(' + quotename(column_name) + ')', ',' + char(13)) + char(13)
+ 'from ' + max(quotename(table_name)) + char(13)
+ ')' + char(13)
+ 'select a.table_name, a.column_name, a.total_sum ' + char(13)
+ 'from cte ' + char(13)
+ 'cross apply (' + char(13)
+ char(9) + 'values' + char(13)
+ string_agg(char(9) + '(''' + table_name + ''', ''' + column_name + ''',' + quotename(column_name) + ')', ',' + char(13)) + char(13)
+ ') a (table_name, column_name, total_sum)'
from information_schema.columns
where table_name = 'table_1'
and data_type = 'money'
print @sql
exec sp_executesql @sql
对于您的示例 table,生成的动态查询是
with cte as (
select
[column_a] = sum([column_a]),
[column_b] = sum([column_b]),
[column_c] = sum([column_c])
from [table_1]
)
select a.table_name, a.column_name, a.total_sum
from cte
cross apply (
values
('table_1', 'column_a',[column_a]),
('table_1', 'column_b',[column_b]),
('table_1', 'column_c',[column_c])
) a (table_name, column_name, total_sum)
编辑
使用循环迭代每个 table。基本上它对每个 table 执行上面的查询并将结果插入临时 table
对于没有 string_agg() 的早期 SQL 服务器版本,使用 for xml path
select @sql = 'with cte as (' + char(13)
+ 'select' + char(13)
+ stuff
(
(
select ',' + quotename(COLUMN_NAME) + ' = sum(' + quotename(COLUMN_NAME) + ')'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table
and DATA_TYPE = 'money'
for xml path('')
),
1, 1, ''
) + char(13)
+ 'from ' + max(quotename(@table)) + char(13)
+ ')' + char(13)
+ 'select a.table_name, a.column_name, a.total_sum ' + char(13)
+ 'from cte ' + char(13)
+ 'cross apply (' + char(13)
+ char(9) + 'values' + char(13)
+ stuff
(
(
select ',' + '(''' + TABLE_NAME + ''', ''' + COLUMN_NAME + ''',' + quotename(COLUMN_NAME) + ')'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table
and DATA_TYPE = 'money'
for xml path('')
),
1, 1, ''
)
+ ') a (table_name, column_name, total_sum)' + char(13)
我正在尝试从数据库中多个 table 的特定数据类型(金钱)的列中获取总和。目前我能够从特定的 table 中获取列列表,但我无法从这些列中获取总和。
这就是我现在拥有的
use database 1
Select + Column_Name
From information_schema.columns
Where TABLE_NAME = 'claimant'
and data_type = 'money'
结果如下所示
table_name | column_name |
---|---|
table_1 | column_a |
table_1 | column_b |
table_1 | column_c |
我想要什么
table_name | column_name | total_sum |
---|---|---|
table_1 | column_a | 66.20 |
table_1 | column_b | 300.50 |
table_1 | column_c | 5389.42 |
@Squirrel 的更新这是我的代码,但它仍然给我带来截断问题。
{
declare @sql nvarchar(max);
select @sql = 'with cte as (' + char(13)
+ 'select' + char(13)
+ string_agg(char(9) + quotename(column_name) + ' = sum(' + quotename(COLUMN_NAME) + ')', ',' + char(13)) + char(13)
+ 'from ' + max(quotename(table_name)) + char(13)
+ ')' + char(13)
+ 'select a.table_name, a.column_name, a.total_sum ' + char(13)
+ 'from cte ' + char(13)
+ 'cross apply (' + char(13)
+ char(9) + 'values' + char(13)
+ string_agg(char(9) + '(''' + table_name + ''',''' + column_name + ''',' + quotename(COLUMN_NAME) + ')', ',' + char(13)) + char(13)
+ ') a (table_name, column_name, total_sum)'
from information_schema.columns AS A
INNER JOIN EDL01.STAGING.TABLE_DETAILS B
ON A.TABLE_NAME = B.DEST_TABLE_NAME
where A.table_name = B.DEST_TABLE_NAME
and data_type = 'money'
print @sql
exec sp_executesql @sql
}
下面是创建table
CREATE TABLE [staging].[TABLE_DETAILS](
[SOURCE_TABLE_NAME] [varchar](100) NULL,
[DEST_TABLE_NAME] [varchar](100) NULL,
[TYPE] [varchar](10) NULL,
[PRIORITY] [int] NULL,
[SOURCE_TABLE_DATABASE] [varchar](50) NULL,
[SOURCE_TABLE_SCHEMA] [varchar](50) NULL,
[DEST_TABLE_DATABASE] [varchar](50) NULL,
[DEST_TABLE_SCHEMA] [varchar](50) NULL
) ON [PRIMARY]
GO
以下是部分结果
select a.table_name, a.column_name, a.total_sum
from cte
cross apply (
values
('PAYMENT','BILLEDAMOUNT',[BILLEDAMOUNT]),
('PAYMENT','AMOUNT',[AMOUNT]),
('SIMS_PAYMENT','CHECKAMOUNT',[CHECKAMOUNT]),
('BILLREVIEWHEADER','JURISDICTIONAMOUNT1',[JURISDICTIONAMOUNT1]),
('BILLREVIEWHEADER','JURISDICTIONAMOUNT2',[JURISDICTIONAMOUNT2]),
('BILLREVIE
您需要动态形成查询,然后使用 sp_executesql
或 exec()
注意:char(9)
是制表符,char(13)
是回车符return。添加这些是为了格式化查询,以便在您 print
进行验证时它是可读的。
declare @sql nvarchar(max);
select @sql = 'with cte as (' + char(13)
+ 'select' + char(13)
+ string_agg(char(9) + quotename(column_name) + ' = sum(' + quotename(column_name) + ')', ',' + char(13)) + char(13)
+ 'from ' + max(quotename(table_name)) + char(13)
+ ')' + char(13)
+ 'select a.table_name, a.column_name, a.total_sum ' + char(13)
+ 'from cte ' + char(13)
+ 'cross apply (' + char(13)
+ char(9) + 'values' + char(13)
+ string_agg(char(9) + '(''' + table_name + ''', ''' + column_name + ''',' + quotename(column_name) + ')', ',' + char(13)) + char(13)
+ ') a (table_name, column_name, total_sum)'
from information_schema.columns
where table_name = 'table_1'
and data_type = 'money'
print @sql
exec sp_executesql @sql
对于您的示例 table,生成的动态查询是
with cte as (
select
[column_a] = sum([column_a]),
[column_b] = sum([column_b]),
[column_c] = sum([column_c])
from [table_1]
)
select a.table_name, a.column_name, a.total_sum
from cte
cross apply (
values
('table_1', 'column_a',[column_a]),
('table_1', 'column_b',[column_b]),
('table_1', 'column_c',[column_c])
) a (table_name, column_name, total_sum)
编辑 使用循环迭代每个 table。基本上它对每个 table 执行上面的查询并将结果插入临时 table
对于没有 string_agg() 的早期 SQL 服务器版本,使用 for xml path
select @sql = 'with cte as (' + char(13)
+ 'select' + char(13)
+ stuff
(
(
select ',' + quotename(COLUMN_NAME) + ' = sum(' + quotename(COLUMN_NAME) + ')'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table
and DATA_TYPE = 'money'
for xml path('')
),
1, 1, ''
) + char(13)
+ 'from ' + max(quotename(@table)) + char(13)
+ ')' + char(13)
+ 'select a.table_name, a.column_name, a.total_sum ' + char(13)
+ 'from cte ' + char(13)
+ 'cross apply (' + char(13)
+ char(9) + 'values' + char(13)
+ stuff
(
(
select ',' + '(''' + TABLE_NAME + ''', ''' + COLUMN_NAME + ''',' + quotename(COLUMN_NAME) + ')'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table
and DATA_TYPE = 'money'
for xml path('')
),
1, 1, ''
)
+ ') a (table_name, column_name, total_sum)' + char(13)