简体   繁体   English

具有COUNT()和SUM()以及TOTAL列的动态PIVOT表SQL Server 2012

[英]Dynamic PIVOT table SQL Server 2012 with COUNT() and SUM() and a TOTAL column

What I'm trying to do (the name of the column is passed dynamically, but I hard-coded it, so it seems simpler in this question): 我正在尝试做的事情(列名是动态传递的,但是我对其进行了硬编码,因此在此问题中看起来更简单):

I am trying to query a database using PIVOT tables to sum one field and count the rows of a SQL Server 2012 table , but, in addition, I am trying to retrieve totals to the COUNT() and SUM() functions . 我正在尝试使用PIVOT表查询数据库以求和一个字段并计算SQL Server 2012表的行 ,但是,此外,我正在尝试将总数返回到COUNT()和SUM()函数

Normally, a pivot table would look like this (which is simpler than what I am trying to reach): 通常,数据透视表如下所示(这比我尝试达到的要简单):

 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) 
在此处输入图片说明 But, I wanted to include the total (grand total) as a column, than I followed this tutorial and everything went alright. 但是,我想将总计(总计)作为一列包括在内,而不是按照本教程进行操作 ,一切都很好。

What I have so far (that's working): 到目前为止,我所拥有的(正在运行):

 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) 
在此处输入图片说明 But, as I did for COUNT(), I would like to do for the SUM() and retrieve both in the same query. 但是,就像我对COUNT()所做的那样,我想对SUM()进行处理并在同一查询中检索两者。

What I tried so far to do what I aim to: 到目前为止,我为实现我的目标所做的努力:

  1. I duplicated the PIVOT part and tried to do a FULL OUTER JOIN , but the problem is that it is repeating the columns to the final result what generates an error (Invalid column name). 我复制了PIVOT部分,并尝试执行FULL OUTER JOIN ,但是问题是,它会将列重复到最终结果,从而产生错误(无效的列名)。 When I print @resultado, there it is, columns are duplicating. 当我打印@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. I tried to UNPIVOT and PIVOT method which generates an error of invalid columns as well. 我尝试使用UNPIVOT和PIVOT方法 ,该方法也会生成无效列的错误。

So needless to say doing anything dynamic is highly problematic since you never really get a handle on your metadata. 因此,不用说进行任何动态处理都是非常有问题的,因为您永远无法真正掌握元数据。 And in any case it's more acceptable when you have multiple conditional aggregations like this to coalesce your different measures using CASE statements, something like 在任何情况下,当您有多个这样的条件聚合来使用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],'

and just build up a single query this way against your dataset. 并以此方式针对您的数据集建立一个查询。

Anyway, to answer your specific issue, if you want to combine these two you have to provide unique column names which means you need to create slightly different versions of @campos and @total. 无论如何,要解决您的特定问题,如果要将两者结合使用,则必须提供唯一的列名,这意味着您需要创建@campos和@total略有不同的版本。 Here I've just done @campos to give you the idea. 在这里,我刚刚完成了@campos来为您提供想法。

Notice I also had to change hc_key to hc_key2 in the second pivot to also avoid duplicate column names. 注意,我还必须在第二个枢轴中将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)  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM