【发布时间】:2021-06-07 10:01:15
【问题描述】:
动态枢轴结合静态聚合
我有一个看起来像这样的表:
Place State Category CategCount MCount Buys Cost
London UK Old 3 NULL 22 4.50
London UK Old 6 5 3 22.00
Brussels BE Young 2 NULL 4 3.50
Brussels BE M NULL 5 12 1.20
Brussels BE M NULL 2 1 1.20
我基本上需要:
- 按多个字段分组(例如,地点、州、类别)
- 按此类组计数
- 每个组的总和 MCount、成本(以及其他,不在示例中),这些列是静态的
- 透视类别并为每个此类分组类别(此处为 Old、Young)求和 CategCount。这是动态部分
结果应如下所示:
Count Place State Category SumMCount SumOld SumYoung SumCost SumBuys
2 London UK Old 5 9 0 26.50 25
1 Brussels BE Young 0 0 2 3.50 4
2 Brussels BE NULL 7 0 0 2.40 13
我知道如何获取动态数据透视查询(根据https://stackoverflow.com/a/38505375/111575),并且我知道如何执行静态部分。 但我不知道如何将两者结合起来。有人有什么想法吗?也许我做错了?
到目前为止我得到了什么:
以下内容为我提供了 Old 和 Young 的正确动态透视结果,但不确定如何将计数和“常规”总和/聚合添加到其中:
create table #temp
(
Place nvarchar(20),
State nvarchar(20),
Category nvarchar(20) null,
CategCount int null,
MCount int null,
Buys int,
Cost int
)
insert into #temp values ('London', 'UK', 'Old', 3, NULL, 22, 4.50)
insert into #temp values ('London', 'UK', 'Old', 6, 5, 3, 22.00)
insert into #temp values ('Brussels', 'BE', 'Young', 2, NULL, 4, 3.50)
insert into #temp values ('Brussels', 'BE', 'M', NULL, 5, 12, 1.20)
insert into #temp values ('Brussels', 'BE', 'M', NULL, 2, 1, 1.20)
DECLARE @cols AS NVARCHAR(MAX)='';
DECLARE @query AS NVARCHAR(MAX)='';
SELECT @cols = @cols + QUOTENAME(Category) + ',' FROM (select distinct Category from #temp where CategCount IS NOT NULL) as tmp
select @cols = substring(@cols, 0, len(@cols)) --trim "," at end
--select (@cols) as bm
set @query =
'SELECT * from
(
select
sum(CategCount) as totalCatCount,
Category
from #temp
group by Category
) src
pivot
(
max(totalCatCount) for Category in (' + @cols + ')
) piv'
execute(@query)
drop table #temp
返回:
以下是没有旋转的“常规”查询:
select count(*) as count, place, state, category,
sum(ISNULL(CategCount, 0)) as SumCatCount,
sum(ISNULL(MCount, 0)) as SumMCount,
sum(ISNULL(buys, 0)) as SumBuys,
sum(Cost) as SumCost
from #temp
group by place, state, category
返回:
但它应该看起来像这样:
【问题讨论】:
-
您必须将静态查询放入动态查询中。对于这样的事情,通常更容易首先为单个需求编写完整的静态查询,然后使其成为动态查询。然后你就知道你的目标是什么查询,并且只需要让它动态工作。
-
@Larnu,我确实有静态查询,它在我的帖子底部。但我坚持的事情是将两者结合起来。我的意思是,如何在某些列而不是其他列上进行旋转,但全部返回?或者您是否建议完全编写动态查询并放弃枢轴(即“手动”执行)?
-
您应该知道,视图不仅不允许动态代码,它们还需要一个固定的(预定义的)列集。动态 SQL 可以使用视图,但视图不能使用也不能是动态的。
-
@RBarryYoung,谢谢,我不知道。因此,即使您将其填充到存储过程中,视图仍然不允许它,对吧?虽然我可以做相反的事情,写一个 SP 而不是一个视图,它没有那个限制。
-
@Abel 正确。有一两个晦涩难懂的技巧可以绕过动态 SQL 的限制,但即便如此,视图也必须有一个预定义的列集,就像表和表值函数一样。程序没有任何限制。
标签: sql sql-server tsql sql-server-2014