sql - sql将两列旋转到相同的列值
问题描述
我正在尝试转换数据,并且到目前为止已经成功地完成了它,但现在已经走到了死胡同,并在我的问题上寻求一些帮助。
我的数据中有四列。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 子句的帮助下使用 pivot&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
解决方案
推荐阅读
- javascript - 将变量声明为多个状态值
- azure-devops - Service Fabric、Azure Devops 部署失败:指定的网络密码不正确
- google-apps-script - 用于多张工作表的 Google 表格 OnEdit 功能
- python - 在这种情况下,python 中的多重赋值如何?
- java - 有没有办法只显示过滤后的结果?
- monaco-editor - 摩纳哥编辑器:自定义撤消/重做
- r - 将 .SDcols 和 .SD 与 data.table 中的两组列一起使用
- go - 是否可以在不添加接口的情况下存根/模拟函数调用?
- javascript - 创建与数组中的数字不同的随机数
- r - 创建新文件时Rstudio setwd不存在