一、行转列【CASE WHEN】
1、背景
项目中需要开发一张报表,根据牌号来分组,选择年月,导出年月范围的数据。
2、虚拟表
-- Oracle数据库
DROP TABLE T_TEST_TT;
CREATE TABLE T_TEST_TT (
PH VARCHAR2(50 BYTE) VISIBLE ,
NY VARCHAR2(10 BYTE) VISIBLE ,
XS NUMBER(11,4) VISIBLE ,
ZB NUMBER(11,4) VISIBLE ,
JG NUMBER(11,4) VISIBLE ,
CB NUMBER(11,4) VISIBLE
);
COMMENT ON COLUMN T_TEST_TT.PH IS '牌号';
COMMENT ON COLUMN T_TEST_TT.NY IS '年月';
COMMENT ON COLUMN T_TEST_TT.XS IS '销售';
COMMENT ON COLUMN T_TEST_TT.ZB IS '占比';
COMMENT ON COLUMN T_TEST_TT.JG IS '价格';
COMMENT ON COLUMN T_TEST_TT.CB IS '成本';
3、SQL
根据牌号【PH】分组,将年月【NY】行转列,求各月份销售【XS】的和
SELECT
PH,
SUM(CASE WHEN NY = '202301' THEN XS ELSE 0 END) XS202301,
SUM(CASE WHEN NY = '202302' THEN XS ELSE 0 END) XS202302
FROM
T_TEST_TT
WHERE
NY >= '202301' AND NY <= '202302'
GROUP BY
PH
获得数据后,可以根据销售【XS】+年月【NY】,在数据集合取出来,存放到EXCEL的特定位置。
二、列转行【UNION/UNION ALL】
把【XS】和【ZB】转为多行同一列
三、行分组转列
MySql
group_concat
-- MySql
DROP TABLE IF EXISTS T_TEST_TT;
CREATE TABLE T_TEST_TT (
PH VARCHAR(50 ) COMMENT '牌号' ,
NY VARCHAR(10 ) COMMENT '年月' ,
XS DECIMAL(11,4) COMMENT '销售' ,
ZB DECIMAL(11,4) COMMENT '占比' ,
JG DECIMAL(11,4) COMMENT '价格' ,
CB DECIMAL(11,4) COMMENT '成本'
);
INSERT INTO `t_test_tt` VALUES ('牌号1', '202301', 63349.3360, 7.8000, NULL, NULL);
INSERT INTO `t_test_tt` VALUES ('牌号1', '202302', 63349.3360, 7.8000, NULL, NULL)
Oracle
WM_CONCAT
如果不能用 替换 :listagg (SAGE, ',') WITHIN GROUP (ORDER BY SAGE)
listagg(合并字段,'连接符号') within group (order by 字段) 来实现列转行