SQL Server中具有行求和的Pivot

SQL Server中具有行求和的Pivot,sql,sql-server,tsql,pivot,Sql,Sql Server,Tsql,Pivot,表A: PID 品牌名称 1. 品牌1 2. 品牌2 3. 品牌3 4. 品牌4 5. 品牌5 6. 品牌6 7. 品牌7 8. 品牌8 你的问题中几乎没有什么错误。首先,您选择的列“Slab”不在表中,这可能是由于从另一个查询中复制而导致的,您需要选择custno和name 然后您的查询将运行,但每个客户将有三行,因为每个客户在数量字段中有三个不同的值。原因是内部查询中的group by子句group by CustNo、[Name]、BrandName、Qty。相反,我使用窗口函数为每个客户

表A:

PID 品牌名称 1. 品牌1 2. 品牌2 3. 品牌3 4. 品牌4 5. 品牌5 6. 品牌6 7. 品牌7 8. 品牌8
你的问题中几乎没有什么错误。首先,您选择的列“Slab”不在表中,这可能是由于从另一个查询中复制而导致的,您需要选择custno和name

然后您的查询将运行,但每个客户将有三行,因为每个客户在数量字段中有三个不同的值。原因是内部查询中的group by子句group by CustNo、[Name]、BrandName、Qty。相反,我使用窗口函数为每个客户计算金额

我还使用了两组动态列名来消除结果中的空值。一个是在代码@cols中使用的枢轴,另一个列表包含coalescecolumnname,0用于将null转换为0

如果您使用的是SQL Server 2017及更高版本,那么我建议您使用string_agg来连接列名,因为它在性能上更容易、更快。我在Query2中使用过它

架构和插入语句:

create table [Table-A](PID int, BrandName varchar(50));
insert into [Table-A] values(1  ,'Brand1');
insert into [Table-A] values(2  ,'Brand2');
insert into [Table-A] values(3  ,'Brand3');
insert into [Table-A] values(4  ,'Brand4');
insert into [Table-A] values(5  ,'Brand5');
insert into [Table-A] values(6  ,'Brand6');
insert into [Table-A] values(7  ,'Brand7');
insert into [Table-A] values(8  ,'Brand8');

create table [TABLE-B]( CustNo  int,Name varchar(10),BrandName varchar(50),Qty int, Amt int);
insert into [TABLE-B] values(1  ,'C1',  'Brand1',   3,  300);
insert into [TABLE-B] values(1  ,'C1',  'Brand2',   2,  400);
insert into [TABLE-B] values(1  ,'C1',  'Brand4',   1,  300);
insert into [TABLE-B] values(1  ,'C1',  'Brand5',   2,  100);
insert into [TABLE-B] values(2  ,'C2',  'Brand1',   2,  200);
insert into [TABLE-B] values(2  ,'C2',  'Brand3',   1,  200);
insert into [TABLE-B] values(3  ,'C3',  'Brand2',   1,  300);
insert into [TABLE-B] values(3  ,'C3',  'Brand7',   3,  150);
查询1使用的内容和xml路径

DECLARE @cols AS NVARCHAR(MAX),
    @colsForSelect AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)
 
 
SET @colsForSelect = STUFF((SELECT  ',' + ' Coalesce('+quotename(BrandName)+',0) '+ quotename(BrandName)
            FROM [TABLE-A] order by pid
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
        
select @cols = STUFF((SELECT ',' + QUOTENAME(BrandName) from [TABLE-A] order by PID FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')

set @query = 'SELECT custno,name,' + @colsForSelect + ',Amt
             from 
             (
select CustNo,[Name],Qty,SUM(cast([amt] as float))over(partition by custno) as Amt,BrandName from [TABLE-B]             ) x
            pivot 
            (
                max(Qty)
                for brandname in (' + @cols + ')
            ) p '

execute(@query)
输出:

卡斯特诺 名称 品牌1 品牌2 品牌3 品牌4 品牌5 品牌6 品牌7 品牌8 金额 1. C1 3. 2. 0 1. 2. 0 0 0 1100 2. C2 2. 0 1. 0 0 0 0 0 400 3. C3 0 1. 0 0 0 0 3. 0 450
你犯了什么错误?问题是什么?您已经编写了一些代码,但您对其不满意,因此请描述错误所在。除非您根据不同的类别需要不同数量的列,否则您可以轻松地使用静态pivot,在pivot的in部分枚举列。尽管这解决了问题,但它不太可能帮助OP以外的人,因为需要读者用眼睛解析代码。请澄清问题:哪里错了,应该做什么,为什么。我没有。我刚刚从dbfiddle.uk复制了标记文本。@astentx我试图解释。@DaleK我现在就尝试做这个表单。谢谢你,伙计。