sql将两列枢转到相同的列值

时间:2019-05-07 15:23:54

标签: sql oracle

我正在尝试转换数据,到目前为止已经取得了一定的成功,但是现在已经走到了尽头,正在寻求有关我的问题的帮助。

我的数据中有四列。 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

0 个答案:

没有答案