如何对动态数据透视表进行分组

时间:2019-06-10 14:43:23

标签: sql sql-server

我有一个存储过程,可以按年月对每个总和结果进行动态表分组,但是分组不好,而且我找不到需要改变的地方才能正常工作

我已经尝试在c#实体框架中复制代码,但是结果相同却不起作用

DECLARE @fch1 NVARCHAR(10) = '2019-01-01';
DECLARE @fch2 NVARCHAR(10) = '2019-05-31';

DECLARE @query NVARCHAR(MAX);

Declare  @colc nvarchar(MAX) = STUFF((SELECT DISTINCT','+QUOTENAME(concat(year(e.FECHADOCTO),month(e.FECHADOCTO),'C'))
                         FROM EDocumentos e WHERE e.FECHADOCTO between @fch1 and @fch2
                         FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '');
Declare  @colv nvarchar(MAX) = STUFF((SELECT DISTINCT','+QUOTENAME(concat(year(e.FECHADOCTO),month(e.FECHADOCTO),'V'))
                         FROM EDocumentos e WHERE e.FECHADOCTO between @fch1 and @fch2
                         FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '');
Declare  @colf nvarchar(MAX) = STUFF((SELECT DISTINCT','+QUOTENAME(concat(year(e.FECHADOCTO),month(e.FECHADOCTO),'F'))
                         FROM EDocumentos e WHERE e.FECHADOCTO between @fch1 and @fch2
                         FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '');
    print @colc;

SET @query = 'SELECT MARCA, '+@colc+','+@colv+','+@colf+' from (
                    SELECT  p.MARCA,
                            concat(year(e.FECHADOCTO),month(e.FECHADOCTO),''C'') as [colc],
                            concat(year(e.FECHADOCTO),month(e.FECHADOCTO),''V'') as [colv],
                            concat(year(e.FECHADOCTO),month(e.FECHADOCTO),''F'') as [colf],
                            sum(d.CANTIDAD) as cant, 
                            sum(d.TOTAL-d.TDESCU) as venta,
                            (sum(d.TOTAL-d.TDESCU)/sum(d.COSTO*d.CANTIDAD)) as factor
                    from    EDocumentos e left join DDocumentos d on e.CVE_DOCTO=d.CVE_DOCTO
                            left join Productos p on d.CVE_PRODUCTO=p.CVE_PRODUCTO
                            left join Vendedores v on e.CVE_VEND=v.CVE_VEND
                    where   e.FECHADOCTO between '''+@fch1+''' and '''+@fch2+'''
                            and v.CLASIFICACION in (''CTRAL'',''DEPTO'',''COMPA'', ''OFICI'', ''BAZAR'', ''INSTA'')
                            and e.ESTADO <> ''C'' and e.TIPODOCTO = ''F'' 
                    group   by  p.MARCA, year(e.FECHADOCTO), month(e.FECHADOCTO) 
                    )x
                    pivot (sum(cant) for [colc] in ('+@colc+')) as pc
                    pivot (sum(venta) for [colv] in ('+@colv+')) as pv
                    pivot (avg(factor) for [colf] in ('+@colf+')) as pf';
print @query;
EXECUTE (@query);

这些是实际结果 actual

这是预期的结果 expected

1 个答案:

答案 0 :(得分:0)

检查此示例,其中不包含动态部分,因此您可以看到查询的外观:

SQL DEMO

  • cte 中,您计算​​出SUMAVG
  • base 中创建标签,然后在标签上进行数据透视
    • 您也可以用UNPIVOT代替UNION ALL,但我认为这种情况不是必需的。
  • 然后您可以进行常规枢轴操作(以后可以在此处包含动态部件)

查询:

with cte as (
  SELECT [type], [years], MAX([value]) as maxv, AVG([value]) as avgv
  FROM Table1
  GROUP BY [type], [years]
), 
base as (
  SELECT [type], cast([years] as nvarchar) + '_maxv' as calc, maxv as value
  FROM cte
  UNION ALL
  SELECT [type], cast([years] as nvarchar) + '_avgv' as calc, avgv as value
  FROM cte
)

SELECT [type], [2017_maxv], [2017_avgv], [2018_maxv], [2018_avgv] 
FROM ( SELECT [type], [calc], [value]
       FROM base ) p
PIVOT ( 
        MAX(value) FOR
        calc IN ([2017_maxv], [2017_avgv], [2018_maxv], [2018_avgv])
       ) as pvt

输出

| type | 2017_maxv | 2017_avgv | 2018_maxv | 2018_avgv |
|------|-----------|-----------|-----------|-----------|
|    A |        10 |        10 |        20 |        20 |
|    B |        30 |        30 |        40 |        40 |