我正在尝试转换数据,到目前为止已经取得了一定的成功,但是现在已经走到了尽头,正在寻求有关我的问题的帮助。
我的数据中有四列。 Cat1(旧类别),val1(旧值),cat2(新类别或当前类别)和val2(其当前值)。
我想要的是cat 1和cat 2的每个组合val2,其相应列中的旧类别为负,新类别为正。
示例数据:
cat1 cat2 val1 val2
A B 10 30
A A 5 20
C A 33 15
B C 23 20
B A 14 5
C B 18 20
A B 14 0
我正在寻找的结果是:
change A B C
AtoB -30 +30
AtoC 0 0
BtoA -5 +5
BtoC -20 +20
CtoA +15 -15
CtoB +20 -20
在CASE子句的帮助下,我成功使用了ivot&unpivot创建了一个只考虑其中一列的表。所以我每行只得到一个值:
select * from (select
cat1
SUM(
CASE WHEN cat1 = A AND cat2 = B THEN val2*-1 ELSE 0 END
) AtoB,
SUM(
CASE WHEN cat1 = A AND cat2 = C THEN val2*-1 ELSE 0 END
) AtoC,
SUM(
CASE WHEN cat1 = B AND cat2 = C THEN val2*-1 ELSE 0 END
) BtoC,
SUM(
CASE WHEN cat1 = C AND cat2 = B THEN val2*-1 ELSE 0 END
) CtoB,
SUM(
CASE WHEN cat1 = C AND cat2 = A THEN val2*-1 ELSE 0 END
) CtoA,
SUM(
CASE WHEN cat1 = B AND cat2 = A THEN val2*-1 ELSE 0 END
) BtoA
FROM table
group by cat1,cat2)
unpivot (
value for cat in
(AtoB,AtoC,BtoC,CtoB,CtoA,BtoA)) up
pivot (
sum(value) for cat1 in ('A','B','C')
这里的问题是,尽管它们共享值,但我仅在cat1上获得了值,而在cat2上却没有得到。我可以想到的一种解决方案是创建一些复杂的联接,或者保存该表,然后在每行上执行一个新的CASE子句以将值乘以-1,但是感觉这两种解决方案都不太好,那还有一些更好的解决方案,我很想念。
在unpivot子句之后,我最终得到:
cat1 cat value
A AtoB -30
A AtoC 0
B Bto 0
B AtoB 0
... ... ...
PIVOT语句将其转换为
cat A B C
AtoB -30
AtoC
BtoA -5
BtoC -23
CtoA -15
CtoB -20