mysql 中sum (if())与case

摘要:
我只想计算正数加上函数。整个理解方法如下:数据示例:createtablex;插入txvalues,,,,,,,,,,,,,,,,,,,;mysql˃select*fromtx;+-----+-----+-------+-----+|Id|c1|c2|c3|+-------+-------+------+|1|A1|B1|9|||2|A2|B1|7||3|A3|B1|4||4|A4|B1|2|||5|A1|B2|2|6|A2|B2|9|7|A3|B2|8||8|A4|B2|5||9|A1|B3|1||10|A2|B3|8||11|A3|B3|B3|B1|B3|B3 |8|A3|B3 |B3|8 |B1|B1|8|B1|B4|B1|B4 |B4|B4|2|15| A3|B4|6||16|A4|B4|9|17|A1|B4|3|18|A2|B4|5|19|A3|B4|2||20|A4|B4|5 |+-------+-------+------+---------+20rowsinetmysql˃预期结果+-------+------+------+-------+A------+-------------+C1|B1|B2|B4|总计|+------+-------++------+----------------+-------+------+|A1|9|2|1|1|11|11|23|||A2|7|9|8|7|31|A3|4|8|8|8 |8|28||A4|2|5|6|14|27||总计|22|24|23|40|109|+------+------+------+------+------+------+使用SUM生成列+WITH ROLLUP生成摘要行,使用IFNULL将摘要行标题显示为Totalmysql˃SELECT-˃IFNULLASTotal,-˃SUMASB1,-˃SUMASB2,-˃SUMASB3,-˃SUMAS MASB4,-˃SUMASSTOTAL-˃FROMASA-˃GROUPBYc1-˃WITHROLLUP;+--------+--------+-------+--------+---------------+--------+|总计|B1|B2|B3|B4|Total|+-------+-------+------+------+-------+------+|A1|9|2|1|11|23||A2|7|9|9|8|7|31|A3|4|8|8|28||A4|2|5|6|14|27||Total|12|24|23|40|109|+------+-------++------+----------+------+------+--------------+-----+5行扫描,1警告使用SUM生成列+UNION生成摘要行,和IFNULL生成摘要行标题显示为Totalmysql˃selectc1,-˃sumASB1,-˃sumASB2,-˃sumASB3,-˃sumAS B4,SUMASTOTAL-˃fromtx-˃groupbyC1-˃UNION-˃SELECT'OTAL',sumASB1、-˃sumASB2,-˃sumASB3,-˃sumASB4,SUMFROMTX-˃;+--------+--------+-------+-------+---------+|C1 | B1 | B2 | B3 | B4 | TOTAL |+------+------+-----+------+----+------+------+------+|A1 | 9 | 2 | 1 | 11 | 23 | | A2 | 7 | 9 | 8 | 7 | 31 | | A3 | 4 | 8 | 8 | 28 | | A4 | 2 | 5 | 6 | 14 | 27 | | TOTAL |22 | 24 | 23 | 40 | 109 |+------+-------+------+-------+------+---------+------+------+---------+5行集合使用SUM生成列,并且不使用子查询mysql˃selectifnull直接生成结果,-˃sumASB1,-˃sumASB2,-˃sum(如果(c2='

先来一个简单的sum

select sum(qty) as total_qty from inventory_product group by product_id

这样就会统计出所有product的qty.

但是很不幸,我们的系统里面居然有qty为负值。而我只想统计那些正值的qty,加上if function就可以了。 SQL为:

select sum(if(qty > 0, qty, 0)) as total_qty from inventory_product group by product_id

意思是如果qty > 0, 将qty的值累加到total_qty, 否则将0累加到total_qty.

以下是sum(if())的例子:

1
2
3
4
5
select
sum( if( qty > 0, qty, 0)) as total_qty ,
sum( if( qty < 0, 1, 0 )) as negative_qty_count
from inventory_product
group by product_id

上面主要介绍sum (if())的定义,以下是关于数据库行列转换的一些方法整理,也是拷贝其他网友的博客的,做了一些删减。

现整理解法如下:

数据样本:

create table tx(
id int primary key,
c1 char(2),
c2 char(2),
c3 int
);

insert into tx values
(1 ,'A1','B1',9),
(2 ,'A2','B1',7),
(3 ,'A3','B1',4),
(4 ,'A4','B1',2),
(5 ,'A1','B2',2),
(6 ,'A2','B2',9),
(7 ,'A3','B2',8),
(8 ,'A4','B2',5),
(9 ,'A1','B3',1),
(10 ,'A2','B3',8),
(11 ,'A3','B3',8),
(12 ,'A4','B3',6),
(13 ,'A1','B4',8),
(14 ,'A2','B4',2),
(15 ,'A3','B4',6),
(16 ,'A4','B4',9),
(17 ,'A1','B4',3),
(18 ,'A2','B4',5),
(19 ,'A3','B4',2),
(20 ,'A4','B4',5);

mysql> select * from tx;
+----+------+------+------+
| id | c1 | c2 | c3 |
+----+------+------+------+
| 1 | A1 | B1 | 9 |
| 2 | A2 | B1 | 7 |
| 3 | A3 | B1 | 4 |
| 4 | A4 | B1 | 2 |
| 5 | A1 | B2 | 2 |
| 6 | A2 | B2 | 9 |
| 7 | A3 | B2 | 8 |
| 8 | A4 | B2 | 5 |
| 9 | A1 | B3 | 1 |
| 10 | A2 | B3 | 8 |
| 11 | A3 | B3 | 8 |
| 12 | A4 | B3 | 6 |
| 13 | A1 | B4 | 8 |
| 14 | A2 | B4 | 2 |
| 15 | A3 | B4 | 6 |
| 16 | A4 | B4 | 9 |
| 17 | A1 | B4 | 3 |
| 18 | A2 | B4 | 5 |
| 19 | A3 | B4 | 2 |
| 20 | A4 | B4 | 5 |
+----+------+------+------+
20 rows in set (0.00 sec)

mysql>

期望结果

+------+-----+-----+-----+-----+------+
|C1 |B1 |B2 |B3 |B4 |Total |
+------+-----+-----+-----+-----+------+
|A1 |9 |2 |1 |11 |23 |
|A2 |7 |9 |8 |7 |31 |
|A3 |4 |8 |8 |8 |28 |
|A4 |2 |5 |6 |14 |27 |
|Total |22 |24 |23 |40 |109 |
+------+-----+-----+-----+-----+------+

  1. 利用SUM(IF()) 生成列 + WITH ROLLUP 生成汇总行,并利用 IFNULL将汇总行标题显示为 Total

mysql> SELECT
-> IFNULL(c1,'total') AS total,
-> SUM(IF(c2='B1',c3,0)) AS B1,
-> SUM(IF(c2='B2',c3,0)) AS B2,
-> SUM(IF(c2='B3',c3,0)) AS B3,
-> SUM(IF(c2='B4',c3,0)) AS B4,
-> SUM(IF(c2='total',c3,0)) AS total
-> FROM (
-> SELECT c1,IFNULL(c2,'total') AS c2,SUM(c3) AS c3
-> FROM tx
-> GROUP BY c1,c2
-> WITH ROLLUP
-> HAVING c1 IS NOT NULL
-> ) AS A
-> GROUP BY c1
-> WITH ROLLUP;
+-------+------+------+------+------+-------+
| total | B1 | B2 | B3 | B4 | total |
+-------+------+------+------+------+-------+
| A1 | 9 | 2 | 1 | 11 | 23 |
| A2 | 7 | 9 | 8 | 7 | 31 |
| A3 | 4 | 8 | 8 | 8 | 28 |
| A4 | 2 | 5 | 6 | 14 | 27 |
| total | 22 | 24 | 23 | 40 | 109 |
+-------+------+------+------+------+-------+
5 rows in set, 1 warning (0.00 sec)

  1. 利用SUM(IF()) 生成列 + UNION 生成汇总行,并利用 IFNULL将汇总行标题显示为 Total
    mysql> select c1,
    -> sum(if(c2='B1',C3,0)) AS B1,
    -> sum(if(c2='B2',C3,0)) AS B2,
    -> sum(if(c2='B3',C3,0)) AS B3,
    -> sum(if(c2='B4',C3,0)) AS B4,SUM(C3) AS TOTAL
    -> from tx
    -> group by C1
    -> UNION
    -> SELECT 'TOTAL',sum(if(c2='B1',C3,0)) AS B1,
    -> sum(if(c2='B2',C3,0)) AS B2,
    -> sum(if(c2='B3',C3,0)) AS B3,
    -> sum(if(c2='B4',C3,0)) AS B4,SUM(C3) FROM TX
    -> ;
    +-------+------+------+------+------+-------+
    | c1 | B1 | B2 | B3 | B4 | TOTAL |
    +-------+------+------+------+------+-------+
    | A1 | 9 | 2 | 1 | 11 | 23 |
    | A2 | 7 | 9 | 8 | 7 | 31 |
    | A3 | 4 | 8 | 8 | 8 | 28 |
    | A4 | 2 | 5 | 6 | 14 | 27 |
    | TOTAL | 22 | 24 | 23 | 40 | 109 |
    +-------+------+------+------+------+-------+
    5 rows in set (0.00 sec)

  2. 利用SUM(IF()) 生成列,直接生成结果不再利用子查询
    mysql> select ifnull(c1,'total'),
    -> sum(if(c2='B1',C3,0)) AS B1,
    -> sum(if(c2='B2',C3,0)) AS B2,
    -> sum(if(c2='B3',C3,0)) AS B3,
    -> sum(if(c2='B4',C3,0)) AS B4,SUM(C3) AS TOTAL
    -> from tx
    -> group by C1 with rollup ;
    +--------------------+------+------+------+------+-------+
    | ifnull(c1,'total') | B1 | B2 | B3 | B4 | TOTAL |
    +--------------------+------+------+------+------+-------+
    | A1 | 9 | 2 | 1 | 11 | 23 |
    | A2 | 7 | 9 | 8 | 7 | 31 |
    | A3 | 4 | 8 | 8 | 8 | 28 |
    | A4 | 2 | 5 | 6 | 14 | 27 |
    | total | 22 | 24 | 23 | 40 | 109 |
    +--------------------+------+------+------+------+-------+
    5 rows in set (0.00 sec)

  3. 动态,适用于列不确定情况,

mysql> SET @EE='';
mysql> SELECT @EE:=CONCAT(@EE,'SUM(IF(C2='',C2,''',',C3,0)) AS ',C2,',') FROM (SELECT DISTINCT C2 FROM TX) A;

mysql> SET @QQ=CONCAT('SELECT ifnull(c1,'total'),',LEFT(@EE,LENGTH(@EE)-1),' ,SUM(C3) AS TOTAL FROM TX GROUP BY C1 WITH ROLLUP');
Query OK, 0 rows affected (0.00 sec)

mysql> PREPARE stmt2 FROM @QQ;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> EXECUTE stmt2;
+--------------------+------+------+------+------+-------+
| ifnull(c1,'total') | B1 | B2 | B3 | B4 | TOTAL |
+--------------------+------+------+------+------+-------+
| A1 | 9 | 2 | 1 | 11 | 23 |
| A2 | 7 | 9 | 8 | 7 | 31 |
| A3 | 4 | 8 | 8 | 8 | 28 |
| A4 | 2 | 5 | 6 | 14 | 27 |
| total | 22 | 24 | 23 | 40 | 109 |
+--------------------+------+------+------+------+-------+
5 rows in set (0.00 sec)

5.使用case,

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT ifnull(c1,'total')`,
MAX(
CASE
WHEN c2= 'B1' THEN C3
END
) AS B1,
MAX(
CASE
WHEN c2= 'B2' THEN C3
END
) AS B2,
MAX(
CASE
WHEN c2= 'B3' THEN C3
END
) AS B3,
MAX(
CASE
WHEN c2= 'B4' THEN C3
END
) AS B4
FROM tx
GROUP BY c1
  

其实数据库中也可以用 CASE WHEN / DECODE 代替 IF

免责声明:文章转载自《mysql 中sum (if())与case》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇VS2013 ERROR MSB8020在Excel中输入特殊字符下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

微信小程序 webview直接关闭所有回到小程序

解决方案:通过微信浏览器监控返回键和H5跳转小程序。...

MIPS学习笔记(一)

本章涉及MIPS变量声明、数据输入和输出、地址获取、分支跳转语句,基本上对应于任何高级语言的最基本操作。该信息的确切形式因汇编程序而异。在MIPS程序集中,标签是后跟冒号的符号名称。)syscall程序的结尾与C类似,可以调用exit函数来停止程序的执行。停止MIPS程序的一种方法是使用类似于在C中调用exit的方法。MIPS中有一个移动指令,它将一个寄存器...

Ubuntu 下查看CPU 信息命令

看看带有“处理器”一词的行数,即逻辑CPU的数量。因此,您可以在cmd下输入以下命令:cat/proc/cpuinfo|greproprocessor|wc-l因此,C++程序自然会想到使用strstr函数来查找processor关键字的出现次数。...

C# AES的128位、192位、256位加密

这里将不解释C#AES的128位、192位和256位加密原理。这里我们主要讨论AES的CBC加密模式中128位、192位和256位加密之间的差异,并参考对称加密和块加密的四种模式。16位密钥对应128位加密,24位密钥对应192位加密,32位密钥对应256位加密,矢量必须为16位。“);ifthrownewException(”指定的密钥长度不能小于16位。...

win server2008关闭危险端口445,135,137,138,139的方法

在Windowsserver2008系统上,有两种途经可以禁用本地端口:1、通过Windows防火墙2、通过IP安全策略一、通过Windows防火墙禁用端口:1、点击“控制面板-Windows防火墙”,确保启用了Windows防火墙。重复操作,添加135、137、138、139规则然后在新规则属性中,单击筛选器操作选项卡单击下方的添加,并且不要勾选右侧的使用...

koroFileHeader插件快速入门使用教程

插件下载插件可以直接在vscode的扩展中查找koroFileHeader,但是有时候由于网络的问题会查找不到软件。插件配置koroFileHeader支持许多功能,但是不是所有功能都是需要,我们关注往往是如何配置注释内容和注释的一些选项。"fileheader.cursorMode":{//这部分是函数头的配置},"fileheader.customMad...