我需要帮助。
我需要使视图大小与颜色交叉以获得项目平衡
我尝试过常规交叉表,但我不能这样做。
我有这张桌子:
ItemCode ItemName Size Color Balance
--------------------------------------------------
1 Shirt S White 10
1 Shirt M White 10
1 Shirt L White 10
1 Shirt S Black 10
1 Shirt M Black 10
1 Shirt L Black 10
我需要知道如何使用交叉表查询将此表转换为此结果:
ItemCode Item Name Colors S M L
--------------------------------------------------
1 Shirt White 10 10 10
1 Shirt Black 10 10 10
有人可以帮忙吗?
答案 0 :(得分:0)
不确定您尝试了什么,但假设您不需要动态列,基本交叉表(也称为条件聚合)将产生这些结果。
select ItemCode
, ItemName
, Color
, S = MAX(CASE when Size = 'S' then Balance end)
, M = MAX(CASE when Size = 'M' then Balance end)
, L = MAX(CASE when Size = 'L' then Balance end)
from SomeTable
group by ItemCode
, ItemName
, Color
- 编辑 -
您可以使用动态交叉表来解决此问题。我从Jeff Moden和他的文章中学到了这种技巧。 http://www.sqlservercentral.com/articles/Crosstab/65048/
这是一个完整的工作示例,因此这里也有很多设置。
if OBJECT_ID('tempdb..#Something') is not null
drop table #Something
create table #Something
(
ItemCode int
, ItemName varchar(10)
, Size char(1)
, Color varchar(10)
, Balance int
)
insert #Something values
(1, 'Shirt', 'S', 'White', 10)
, (1, 'Shirt', 'M', 'White', 10)
, (1, 'Shirt', 'L', 'White', 10)
, (1, 'Shirt', 'S', 'Black', 10)
, (1, 'Shirt', 'M', 'Black', 10)
, (1, 'Shirt', 'L', 'Black', 10)
declare @StaticPortion nvarchar(2000) =
'with OrderedResults as
(
SELECT s.ItemCode
, s.ItemName
, s.Color
, s.Size
, s.Balance
, ROW_NUMBER() over(partition by s.ItemCode, s.ItemName, s.Color order by s.Size desc) as RowNum
FROM #Something s
)
select ItemCode
, ItemName
, Color';
declare @DynamicPortion nvarchar(max) = '';
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by ItemCode
, ItemName
, Color
order by ItemCode
, ItemName
, Color';
--the following cte is a tally table (another trick I learned from Jeff Moden)
with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E2
)
select @DynamicPortion = @DynamicPortion +
', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then Balance end) as ' + sizes.SizeName + CHAR(10)
from cteTally t
join
(
values
('S', 1)
,('M', 2)
,('L', 3)
) sizes(SizeName, SizeNum) on sizes.SizeNum = t.N --This would be better if you have a table of sizes you can join to
where t.N <=
(
select top 1 Count(s.Size)
FROM #Something s
group by s.ItemCode
, s.ItemName
, s.Color
order by COUNT(*) desc
)
declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion;
--you can comment the following. it is here for now so you can view the dynamic sql before it executes
select @SqlToExecute
--Once you are satisfied that the dynamic sql generated is correct simply uncomment the below line
--exec sp_executesql @SqlToExecute