巧用MySQL的临时变量之二:如何做一个类似excel表单元格合并的效果

巧用MySQL的临时变量之二:如何做一个类似excel表单元格合并的效果?

财务一些变态的数据需求有时会让你很为难!数据导出后后期加工一下好像很简单,但是成千上万行数据时,人工处理就有点烦了,请看这样一个需求如何做?
一个单号有一个收入,可能有多个费用类型的成本。需要单号、收入显示在左边,多个成本显示在右边,要好像excel表的单元格合并,即左边相同单号在第二行显示为空。
在这里插入图片描述
加粉丝看
MySQL技巧系列之《未经证实的葵花宝典》:一篇可以当饭吃的MySQL文章,值得收藏

好吧,为了你,我连呼吸都反复练习。先创建二个测试表及添加一些数据。
DROP TABLE my_ic_table;
CREATE TABLE my_ic_table (
dh_id INT(4) NOT NULL COMMENT ‘单号ID’,
dh VARCHAR(50) NULL COMMENT ‘单号’,
ic_amt DECIMAL(13,2) NULL COMMENT ‘收入’,
PRIMARY KEY (dh_id)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT=‘测试用单号收入表’;

DROP TABLE my_pm_table;
CREATE TABLE my_pm_table (
auto_id INT(4) NOT NULL AUTO_INCREMENT COMMENT ‘明细表的流水ID’,
dh_id INT(4) NULL COMMENT ‘单号ID’,
amt_type VARCHAR(20) NULL COMMENT ‘费用类型’,
pm_amt DECIMAL(13,2) NULL COMMENT ‘成本’,
PRIMARY KEY (auto_id)
) ENGINE=INNODB AUTO_INCREMENT = 0 DEFAULT CHARSET=utf8 COMMENT=‘测试用单号成本表’;

INSERT INTO my_ic_table(dh_id, dh, ic_amt)
VALUES(1,‘9000’,100.00), (2,‘9001’,150.00);

INSERT INTO my_pm_table(dh_id, amt_type, pm_amt)
VALUES(1,‘A’,20.00), (1,‘B’,40.00), (2,‘A’,25.00), (2,‘B’,35.00), (2,‘C’,10.00);
在这里插入图片描述
在这里插入图片描述
数据准备好了,看看如何写脚本生成那个excel表?
SELECT
CASE WHEN @dh <> 单号 THEN @dh := IF(@rownum := 0, 单号, 单号) # 绝招!这样就可以顺便改变 @rownum 标志
ELSE @dh := IF(@rownum := 1, 单号, 单号)
END AS 单号,
IF(@rownum = 0, 收入, ‘’) 收入,
IFNULL(SUM(pm.pm_amt), 0) 成本, pm.amt_type 费用类型
FROM(
SELECT dh_id, dh 单号, ic_amt 收入
FROM my_ic_table
WHERE dh IN (‘9000’,‘9001’)
) Q
LEFT JOIN my_pm_table pm ON Q.dh_id = pm.dh_id
LEFT JOIN (SELECT @rownum := 0, @dh := ‘’) p ON 1=1
GROUP BY 单号, 费用类型
ORDER BY 单号, 费用类型;
#写得非常工整的缩进脚本,粘贴到了这里之后缩进也没了?
非常工整的脚本是这样的
执行后效果如下图
在这里插入图片描述
妙!高!实在是高!

总结:灵活应用MySQL的临时变量,可以使脚本写出很多相当复杂的查询结果。本例中用临时变量@dh记录它的变化,从而控制另一个临时变量@rownum的 0 或1变化,最后通过 IF(@rownum = 0, 收入, ‘’) 收入 来决定单元格要不要显示0。

  • 53
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值