求小计,总计的一个SQL方法。
程序员文章站
2022-03-04 07:51:45
...
--创建表。
CREATE TABLE TBL_REVENUE (
FNAME VARCHAR(20) NOT NULL, --名字
FMONTH INT NOT NULL, --月份
FTYPE INT NOT NULL, --类型(0为收入,1为支出)
FMONEY DECIMAL(10,2) NOT NULL, --金额
FPURPOSE VARCHAR(100) NULL); --用途
--插入数据。
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 1, 0, 7300, '工资' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 1, 1, 200, '交手机费' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 1, 1, 168, '请哥们吃饭' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 1, 1, 600, '给老婆买化妆品' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 1, 1, 600, '吃饭' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 1, 1, 1550, '房租' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 2, 0, 7300, '工资' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 2, 1, 1200, '买手机' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 2, 1, 1550, '房租' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 2, 0, 1300, '发奖金' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老公', 2, 1, 600, '吃饭' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老婆', 1, 0, 4000, '工资' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老婆', 1, 1, 300, '交手机费' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老婆', 1, 1, 1000, '吃饭' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老婆', 1, 1, 2000, '买衣服' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老婆', 2, 0, 4100, '工资' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老婆', 2, 1, 200, '交手机费' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老婆', 2, 1, 700, '吃饭' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('老婆', 2, 1, 158, '买被' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('孩子', 1, 1, 300, '零花钱' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('孩子', 1, 1, 115, '买文具' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('孩子', 1, 1, 86, '交书费' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('孩子', 2, 1, 300, '零花钱' );
INSERT INTO TBL_REVENUE (FNAME, FMONTH, FTYPE, FMONEY, FPURPOSE) VALUES ('孩子', 2, 1, 600, '买衣服和鞋' );
--每个人,每个月的收入和支出算出来。
WITH TBL_BASE
AS (SELECT FNAME,
FMONTH,
SUM(CASE
WHEN FTYPE = 0 THEN FMONEY
ELSE 0
END) IN_MONEY,
SUM(CASE
WHEN FTYPE = 1 THEN FMONEY
ELSE 0
END) OUT_MONEY
FROM TBL_REVENUE
GROUP BY FNAME,FMONTH),
--每个人,每个月的收入和支出算出来,加入是不是小计,总计FLG的值。
TBL_LIST
AS (SELECT FNAME,
FMONTH,
IN_MONEY,
OUT_MONEY,
IN_MONEY
- OUT_MONEY LEFT_MONEY,
FNAME SORT_NM,
0 SUB_FLG,
0 TOTAL_FLG
FROM TBL_BASE),
--以人为单位的收支计算出来,记为“小计”。
TBL_SUB_TOTAL
AS (SELECT '小计' FNAME,
NULL FMONTH,
SUM(IN_MONEY) IN_MONEY,
SUM(OUT_MONEY) OUT_MONEY,
SUM(LEFT_MONEY) LEFT_MONEY,
FNAME SORT_NM,
1 SUB_FLG,
0 TOTAL_FLG
FROM TBL_LIST
GROUP BY FNAME),
--所有人的收支情况,记为“总计”。
TBL_TOTAL
AS (SELECT '总计' FNAME,
NULL FMONTH,
SUM(IN_MONEY) IN_MONEY,
SUM(OUT_MONEY) OUT_MONEY,
SUM(LEFT_MONEY) LEFT_MONEY,
'' SORT_NM,
1 SUB_FLG,
2 TOTAL_FLG
FROM TBL_SUB_TOTAL)
--把每个人以月为单位的统计,以及每个人的小计,家庭的总计统计出来。
SELECT FNAME,
FMONTH,
IN_MONEY,
OUT_MONEY,
LEFT_MONEY
FROM (SELECT FNAME,
FMONTH,
IN_MONEY,
OUT_MONEY,
LEFT_MONEY,
SORT_NM,
SUB_FLG,
TOTAL_FLG
FROM TBL_LIST
UNION ALL
SELECT FNAME,
FMONTH,
IN_MONEY,
OUT_MONEY,
LEFT_MONEY,
SORT_NM,
SUB_FLG,
TOTAL_FLG
FROM TBL_SUB_TOTAL
UNION ALL
SELECT FNAME,
FMONTH,
IN_MONEY,
OUT_MONEY,
LEFT_MONEY,
SORT_NM,
SUB_FLG,
TOTAL_FLG
FROM TBL_TOTAL) TMPTBL
ORDER BY TOTAL_FLG,
SORT_NM,
SUB_FLG,
FMONTH;
--删掉表。
DROP TABLE TBL_REVENUE;
上一篇: SQL_CASE_1
下一篇: Java单元测试