【问题标题】:Dynamic PIVOT table SQL Server 2012 with COUNT() and SUM() and a TOTAL column带有 COUNT() 和 SUM() 以及 TOTAL 列的动态 PIVOT 表 SQL Server 2012
【发布时间】:2016-09-03 13:36:47
【问题描述】:

我正在尝试做的事情(列名是动态传递的,但我是硬编码的,所以这个问题看起来更简单):

我正在尝试使用 PIVOT 表查询数据库以汇总一个字段并计算 SQL Server 2012 表的行数,但此外,我正在尝试检索总计以COUNT() 和 SUM() 函数

通常,数据透视表看起来像这样(这比我想要达到的要简单):

declare @campos nvarchar (max)
select @campos  = coalesce(@campos + ',[' + Setor + ']', '[' + Setor + ']')
from dbo.TbFinanciamentos
group by Setor
order by Setor

declare @resultado nvarchar(max)
set @resultado =
        'select * from(select Setor, ''br-'' + lower(UF_FILIAL) as [hc-key] from dbo.TbFinanciamentos) a
		 pivot(
		     count(Setor)
			 for Setor in(' + @campos + ')
		 ) a'

execute(@resultado)
但是,我想将总数(总计)作为一个列,而不是我关注this tutorial,一切都很好。

到目前为止我所拥有的(正在工作):

declare @campos nvarchar (max)
select @campos  = coalesce(@campos + ',[' + Setor + ']', '[' + Setor + ']')
from dbo.TbFinanciamentos
group by Setor
order by Setor

declare @total nvarchar(max)
select @total = coalesce(@total + 'isnull([' + Setor + '], 0) + ', 'isnull([' + Setor + '], 0) + ')
from dbo.TbFinanciamentos group by Setor order by Setor
set @total = left(@total, len(@total) - 1)

declare @resultado nvarchar(max)
set @resultado =
        'select *, '+ @total +' as [value] into #temp_total
         from (select Setor, ''br-'' + lower(UF_FILIAL) as [hc-key] from dbo.TbFinanciamentos) a
		 pivot(
		     count(Setor)
			 for Setor in(' + @campos + ')
		 ) b
         select * from #temp_total'

execute(@resultado)
但是,就像我为 COUNT() 所做的那样,我想为 SUM() 做并在同一个查询中检索两者。

到目前为止,我为实现我的目标所做的努力:

  1. 我复制了 PIVOT 部分并尝试执行FULL OUTER JOIN,但问题是它重复列到最终结果会产生错误(无效的列名)。当我打印@resultado 时,列在重复。

declare @campos nvarchar (max)
select @campos  = coalesce(@campos + ',[' + Setor + ']', '[' + Setor + ']')
from dbo.TbFinanciamentos
group by Setor
order by Setor

declare @total nvarchar(max)
select @total = coalesce(@total + 'isnull([' + Setor + '], 0) + ', 'isnull([' + Setor + '], 0) + ')
from dbo.TbFinanciamentos group by Setor order by Setor
set @total = left(@total, len(@total) - 1)

declare @resultado nvarchar(max)
set @resultado =
        'select *, '+ @total +' as [value] into #temp_total
         from (
		     (select Setor, ''br-'' + lower(UF_FILIAL) as [hc-key] from dbo.TbFinanciamentos
				 pivot(
					 count(Setor)
					 for Setor in(' + @campos + ')
				 ) as b
			 ) as sth
			full outer join
			(
		     select cast(Valor_do_Emprestimo as float) as Valor_do_Emprestimo, Setor, ''br-'' + lower(UF_FILIAL) as [hc-key] from dbo.TbFinanciamentos
				 pivot(
					 count(Setor)
					 for Setor in(' + @campos + ')
				 ) as b
			 ) as sth_else
			on sth.[hc-key] = sth_else.[hc-key]
		 )
         select * from #temp_total'

execute(@resultado)
  1. 我尝试UNPIVOT and PIVOT method,这也会产生无效列的错误。

【问题讨论】:

  • 你在对哪个字段求和?此处列出的所有字段都是文本字段。
  • 非常感谢您的回复。我正在尝试对“Valor_do_Emprestimo”字段求和。我将发布另一个我尝试使用full outer join 的查询。此查询列出了我要求和的字段。
  • @KyleHale 我将查询添加到我尝试过的事情的第 1 项

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

不用说,做任何动态的事情都是很成问题的,因为你从来没有真正掌握过你的元数据。无论如何,当您有多个这样的条件聚合以使用 CASE 语句合并您的不同度量时,它更容易接受,例如

    SUM(CASE When Setor = ''' + Setor ''' then 1 else 0 end) 
as [' + Setor + '_Count], 
SUM(CASE When Setor = ''' + Setor ''' then Valor_do_Emprestimo else 0 end) 
as [' + Setor + '_Total],'

并以这种方式针对您的数据集构建单个查询。

无论如何,要回答您的具体问题,如果您想将这两者结合起来,您必须提供唯一的列名,这意味着您需要创建稍微不同的@campos 和@total 版本。在这里,我刚刚完成了@campos 来给你一个想法。

请注意,我还必须在第二个数据透视表中将 hc_key 更改为 hc_key2 以避免重复的列名。

declare @campos nvarchar (max)
select @campos  = coalesce(@campos + ',[' + Setor + ']', '[' + Setor + ']')
from dbo.TbFinanciamentos
group by Setor
order by Setor

declare @campos2 nvarchar (max)
select @campos2  = coalesce(@campos2 + ',[' + Setor + '_2]', '[' + Setor + '_2]')
from dbo.TbFinanciamentos
group by Setor
order by Setor

declare @total nvarchar(max)
select @total = coalesce(@total + 'isnull([' + Setor + '], 0) + ', 'isnull([' + Setor + '], 0) + ')
from dbo.TbFinanciamentos group by Setor order by Setor
set @total = left(@total, len(@total) - 1)

declare @resultado nvarchar(max)
set @resultado =
        'select * into #temp_total from (
        select *, '+ @total +' as [value]          from
        (
             select * from (select Setor, ''br-'' + lower(UF_FILIAL) as [hc-key] from dbo.TbFinanciamentos) pvt
                 pivot(
                     count([Setor])
                     for Setor in(' + @campos + ')
                 ) as b
             ) as sth
            full outer join
            (
               select *          from (
             select * from (select cast(Valor_do_Emprestimo as float) as Valor_do_Emprestimo, Setor+''_2'' as Setor, ''br-'' + lower(UF_FILIAL) as [hc-key2] from dbo.TbFinanciamentos ) pvt
                 pivot(
                    sum([Valor_do_Emprestimo])
                     for Setor in(' + @campos2 + ')
                 ) as b
             ) c
            ) as sth_else
            on sth.[hc-key] = sth_else.[hc-key2]
         ) d

         select * from #temp_total'
        execute(@resultado)  

【讨论】:

  • 它的工作原理就像一个 cham。非常感谢你,凯尔。不用说,你帮了我很多。再次感谢您!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 2020-10-19
相关资源
最近更新 更多