控制流函数

case()函数

  • 如果满足WHEN分支中的条件,则返回THEN分支中的相应结果,否则返回ELSE分支中的结果
  • CASE表达式是一个流控制结构,允许在查询中构造条件,例如:SELECT或WHERE子句。 MySQL提供了两种形式的CASE表达式

case形式一

CASE value
WHEN compare_value_1 THEN result_1
WHEN compare_value_2 THEN result_2
…
ELSE result END

如果value等于compare_value,例如compare_value_1compare_value_2等,则CASE表达式返回相应的结果,即result_1result_2。 如果值不与任何compare_value匹配,则CASE表达式将返回ELSE子句中指定的结果。

case形式二

CASE
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
…
ELSE result END

在第二种形式中,如果条件为True,则CASE表达式返回结果,如result_1result_2等。 如果所有条件都为false,则返回ELSE部分中的结果。如果省略ELSE部分,CASE表达式将返回NULL

CASE表达式返回的数据类型取决于使用它的上下文的结果。 例如,如果在字符串上下文中使用CASE表达式,则会以字符串形式返回结果。 如果在数值上下文中使用CASE表达式,则会以整数,小数或实数值的形式返回结果。

case函数示例

假设您要按状态对客户进行排序,如果状态为NULL,则要使用国家作为排序标准。要实现这一点,您可以使用第一种形式的CASE表达式如下

SELECT customerName, state, country
FROMcustomers
ORDER BY (CASEWHEN state IS NULL THEN countryELSE state
END);

if语句

  • 根据给定的条件返回一个值

  • MySQL IF语句允许您根据表达式的某个条件或值结果来执行一组SQL语句。 要在MySQL中形成一个表达式,可以结合文字,变量,运算符,甚至函数来组合。表达式可以返回TRUE,FALSENULL,这三个值之一

  • IF语句语法

    IF expression THEN statements;
    END IF;
    

    如果表达式(expression)计算结果为TRUE,那么将执行statements语句,否则控制流将传递到END IF之后的下一个语句

  • IF ELSE 语句

    IF expression THENstatements;
    ELSEelse-statements;
    END IF;
    

    如果表达式计算结果为FALSE时执行语句,请使用IF ELSE语句

  • IF ELSEIF ELSE语句

    IF expression THENstatements;
    ELSEIF elseif-expression THENelseif-statements;
    ...
    ELSEelse-statements;
    END IF;
    

    如果表达式(expression)求值为TRUE,则IF分支中的语句(statements)将执行;如果表达式求值为FALSE,则如果elseif_expression的计算结果为TRUE,MySQL将执行elseif-expression,否则执行ELSE分支中的else-statements语句

IF语句示例

以下示例说明如何使用IF ESLEIF ELSE语句,GetCustomerLevel()存储过程接受客户编号和客户级别的两个参数。

首先,它从customers表中获得信用额度

然后,根据信用额度,它决定客户级别:PLATINUM , GOLDSILVER

参数p_customerlevel存储客户的级别,并由调用程序使用

DELIMITER $$CREATE PROCEDURE GetCustomerLevel(in  p_customerNumber int(11), out p_customerLevel  varchar(10))
BEGINDECLARE creditlim double;SELECT creditlimit INTO creditlimFROM customersWHERE customerNumber = p_customerNumber;IF creditlim > 50000 THENSET p_customerLevel = 'PLATINUM';ELSEIF (creditlim <= 50000 AND creditlim >= 10000) THENSET p_customerLevel = 'GOLD';ELSEIF creditlim < 10000 THENSET p_customerLevel = 'SILVER';END IF;END$$

ifnull() 函数

  • 如果第一个参数不为NULL,则返回第一个参数,否则返回第二个参数
  • IFNULL函数是MySQL控制流函数之一,它接受两个参数,如果不是NULL,则返回第一个参数。 否则,IFNULL函数返回第二个参数

语法

IFNULL(expression_1,expression_2);

如果expression_1不为NULL,则IFNULL函数返回expression_1; 否则返回expression_2的结果

IFNULL示例

示例-1

SELECT IFNULL(1,0); -- returns 1

示例-2

SELECT IFNULL('',1); -- returns ''

示例-3

SELECT IFNULL(NULL,'IFNULL function'); -- returns IFNULL function

上面示例中的语句是怎么运行的?

  • IFNULL(1,0)返回1,因为1不为NULL
  • IFNULL('',1)返回'',因为''字符串不为NULL
  • IFNULL(NULL,'IFNULL function')返回IFNULL函数字符串,因为第一个参数为NULL
    我们来看一下使用IFNULL函数的实例。

首先,使用以下语句创建一个名为contacts的新表:

USE testdb;
CREATE TABLE IF NOT EXISTS contacts (contactid INT AUTO_INCREMENT PRIMARY KEY,contactname VARCHAR(20) NOT NULL,bizphone VARCHAR(15),homephone VARCHAR(15)
);

每个联系人都有一个名字,业务电话和家庭电话。

其次,将数据插入到contacts表中:

INSERT INTO contacts(contactname,bizphone,homephone)
VALUES('John Doe','(541) 754-3009',NULL),('Cindy Minsu',NULL,'(541) 754-3110'),('Sue Greenspan','(541) 754-3010','(541) 754-3011'),('Lily Bush',NULL,'(541) 754-3111');

一些联系人只有家庭电话或商务电话。要从contacts表中获取所有联系人姓名和电话,请使用以下查询:

SELECT contactName, bizphone, homephone
FROMcontacts;

执行上面查询语句,得到以下结果 -

+---------------+----------------+----------------+
| contactName   | bizphone       | homephone      |
+---------------+----------------+----------------+
| John Doe      | (541) 754-3009 | NULL           |
| Cindy Minsu   | NULL           | (541) 754-3110 |
| Sue Greenspan | (541) 754-3010 | (541) 754-3011 |
| Lily Bush     | NULL           | (541) 754-3111 |
+---------------+----------------+----------------+
4 rows in set

如果联系人的商务电话不可用,可以通过查询获得联系人的家庭电话也是一个获取联系方式的办法 -

SELECT contactname, IFNULL(bizphone, homephone) phone
FROMcontacts;

这可以使用IFNULL()函数来解决。如果bizphoneNULL,则IFNULL函数将返回homephone的值。

第三,使用以下查询获取所有联系人的姓名和电话:

mysql> SELECT contactname, IFNULL(bizphone, homephone) phone
FROMcontacts;
+---------------+----------------+
| contactname   | phone          |
+---------------+----------------+
| John Doe      | (541) 754-3009 |
| Cindy Minsu   | (541) 754-3110 |
| Sue Greenspan | (541) 754-3010 |
| Lily Bush     | (541) 754-3111 |
+---------------+----------------+
4 rows in set

请注意,应避免在WHERE子句中使用IFNULL函数,因为它会降低查询的性能。

如果要检查值是否为NULL,则可以在WHERE子句中使用IS NULLIS NOT NULL

nullif()函数

  • 如果第一个参数等于第二个参数,则返回NULL,否则返回第一个参数

语法

NULLIF(expression_1,expression_2);

如果expression_1 = expression_2true,则NULLIF函数返回NULL,否则返回expression_1

请注意,NULLIF函数与以下使用CASE的表达式类似:

CASE WHEN expression_1 = expression_2THEN NULL
ELSEexpression_1
END;

NULLIF示例

来看一下使用NULLIF函数来了解它的工作原理的一些例子。

示例-1

mysql> SELECT NULLIF(1,1);
+-------------+
| NULLIF(1,1) |
+-------------+
| NULL        |
+-------------+
1 row in set

示例-2

mysql> SELECT NULLIF(1,2);
+-------------+
| NULLIF(1,2) |
+-------------+
|           1 |
+-------------+
1 row in set

示例-3

mysql> SELECT NULLIF('MySQL NULLIF','MySQL NULLIF');
+---------------------------------------+
| NULLIF('MySQL NULLIF','MySQL NULLIF') |
+---------------------------------------+
| NULL                                  |
+---------------------------------------+
1 row in set

示例-4

mysql> SELECT NULLIF('MySQL NULLIF','MySQL IFNULL');
+---------------------------------------+
| NULLIF('MySQL NULLIF','MySQL IFNULL') |
+---------------------------------------+
| MySQL NULLIF                          |
+---------------------------------------+
1 row in set

示例-6

mysql> SELECT NULLIF(1,NULL);
+----------------+
| NULLIF(1,NULL) |
+----------------+
|              1 |
+----------------+
1 row in set

示例-7

mysql> SELECT NULLIF(NULL,1);
+----------------+
| NULLIF(NULL,1) |
+----------------+
| NULL           |
+----------------+
1 row in set

上面示例中的语句是如何工作的?

  • NULLIF(1,1)返回NULL,因为1等于1
  • NULLIF(1,2)返回1,这是第一个参数,因为1不等于2
  • NULLIF('MySQL NULLIF','MySQL NULLIF')返回NULL,因为两个参数是相同的字符串。
  • NULLIF('MySQL NULLIF','MySQL NULLIF')返回MySQL NULLIF,因为两个字符串不相等。
  • NULLIF(1,NULL)返回1,因为1不等于NULL
  • NULLIF(NULL,1)返回第一个参数,即NULL,因为NULL不等于1

使用NULLIF函数来防止除零错误

我们经常使用NULLIF函数来阻止在查询中除以零错误。如果MySQL服务器启用了ERROR_FOR_DIVISION_BY_ZERO模式,则当发生零除数时将发出错误。

见下列查询语句:

SELECT 1/0; -- cause error

上面语句得到以下结果 -

mysql> SELECT 1/0;
+------+
| 1/0  |
+------+
| NULL |
+------+
1 row in set

在这种情况下,您可以使用NULLIF函数来阻止除以零,如下所示:

SELECT 1/NULLIF(0,0); -- return NULL

因为0等于0,所以NULLIF(0,0)表达式返回NULL。结果语句返回NULL

我们来看看示例数据库(yiibaidb)中的orders表,其结构如下所示 -

mysql> desc orders;
+----------------+-------------+------+-----+---------+-------+
| Field          | Type        | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| orderNumber    | int(11)     | NO   | PRI | NULL    |       |
| orderDate      | date        | NO   |     | NULL    |       |
| requiredDate   | date        | NO   |     | NULL    |       |
| shippedDate    | date        | YES  |     | NULL    |       |
| status         | varchar(15) | NO   |     | NULL    |       |
| comments       | text        | YES  |     | NULL    |       |
| customerNumber | int(11)     | NO   | MUL | NULL    |       |
+----------------+-------------+------+-----+---------+-------+
7 rows in set

首先,要获取2013年6月创建的所有订单,请使用以下查询:

SELECT orderNumber, orderdate, requiredDate, shippedDate, status
FROMorders
WHEREorderDate BETWEEN '2013-06-01' AND '2013-06-30';

执行上面查询语句得到以下结果 -

+-------------+------------+--------------+-------------+---------+
| orderNumber | orderdate  | requiredDate | shippedDate | status  |
+-------------+------------+--------------+-------------+---------+
|       10127 | 2013-06-03 | 2013-06-09   | 2013-06-06  | Shipped |
|       10128 | 2013-06-06 | 2013-06-12   | 2013-06-11  | Shipped |
|       10129 | 2013-06-12 | 2013-06-18   | 2013-06-14  | Shipped |
|       10130 | 2013-06-16 | 2013-06-24   | 2013-06-21  | Shipped |
|       10131 | 2013-06-16 | 2013-06-25   | 2013-06-21  | Shipped |
|       10132 | 2013-06-25 | 2013-07-01   | 2013-06-28  | Shipped |
|       10133 | 2013-06-27 | 2013-07-04   | 2013-07-03  | Shipped |
+-------------+------------+--------------+-------------+---------+
7 rows in set

第二,计算2013年6月发货订单数量/取消订单数量,可使用SUM和IF函数。

SELECT SUM(IF(status = 'Shipped',1,0)) / SUM(IF(status = 'Cancelled',1,0))
FROM orders
WHERE orderDate BETWEEN '2013-06-01' and '2013-06-30';

执行上面查询语句,得到以下结果 -

+------------------------------------------------------------------------+
| SUM(IF(status = 'Shipped',1,0)) /SUM(IF(status = 'Cancelled',1,0)) |
+------------------------------------------------------------------------+
| NULL                                                                       |
+------------------------------------------------------------------------+
1 row in set

MySQL发出错误,因为在2013年6月没有创建取消订单。 这意味着表达式SUM(IF(status ='Cancelled',1,0))返回0

第三,为了防止除0错误,您可以使用NULLIF函数,如下查询:

SELECT SUM(IF(status = 'Shipped', 1, 0)) /NULLIF(SUM(IF(status = 'Cancelled', 1, 0)), 0)
FROMorders
WHEREorderDate BETWEEN '2013-06-01' AND '2013-06-30';

执行上面查询语句,得到以下结果 -

+-------------------------------------------------------------------------+
| SUM(IF(status = 'Shipped', 1, 0)) /NULLIF(SUM(IF(status = 'Cancelled', 1, 0)), 0) |
+-------------------------------------------------------------------------+
| NULL                                                                              |
+-------------------------------------------------------------------------+
1 row in set

因为2013年6月没有创建取消订单,所以SUM(IF(status ='Cancelled',1,0))返回0,这也使得NULLIF(SUM(IF(status ='Cancelled',1,0) ,0)表达式返回NULL值。

MySQL高级篇:控制流函数相关推荐

  1. MySQL高级篇知识点——其它数据库日志

    目录 1.其他数据库日志 1.1.日志类型 1.2.日志的弊端 2.慢查询日志 (slow query log) 3.通用查询日志 (general query log) 3.1.问题场景 3.2.查 ...

  2. MySQL高级篇知识点——索引优化与查询优化

    目录 1.数据准备 1.1.建库建表 1.2.创建相关函数 1.3.创建存储过程 1.4.调用存储过程 1.5.删除某表上的索引 2.索引失效案例 2.1.全值匹配 2.2.最佳左前缀匹配原则 2.3 ...

  3. MySQL高级篇(事务视图存储过程与函数)

    目录 一.事务 1.1什么是事务? 1.2事务的特性 1.3事务的分类 1.4事务的操作步骤 1.5事务的隔离级别(面试题常考) 二.视图 2.1视图的操作 2.1.1视图的创建 2.1.2视图更新( ...

  4. mysql高级篇学习笔记

    目录 前言 1 mysql安装及运行(linux环境) 1.1 安装前检查 1.2 MySQL卸载 ①**关闭 mysql 服务** ②**查看当前 mysql 安装状况** ③**卸载上述命令查询出 ...

  5. 【MySQL高级篇笔记-MySQL事务日志(下) 】

    此笔记为尚硅谷MySQL高级篇部分内容 目录 一.redo日志 1.为什么需要REDO日志 2.REDO日志的好处.特点 3.redo的组成 4.redo的整体流程 5.redo log的刷盘策略 6 ...

  6. mysql高级篇(二)mysql索引优化分析

    mysql高级篇笔记 mysql高级篇(一)mysql的安装配置.架构介绍及SQL语句的复习. mysql高级篇(二)mysql索引优化分析. mysql高级篇(三)查询截取分析(慢查询日志).主从复 ...

  7. 程序猿必备技能之MySQL高级篇

      MySQL是我们非常常用的关系型数据库,非常重要,所以在这里给大家整理下MySQL的高级内容. 1. MySQL高级特性 1.1. MySQL体系结构 Client Connectors: 接入方 ...

  8. 【MySQL高级篇】第15章_锁

    第15章_锁 1. 概述 在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的 资源.为保证数据的一致性,需要对 并发操作进行控制 ,因此产生了 锁 .同 ...

  9. MySQL高级篇知识点——数据库的设计规范

    目录 1.为什么需要数据库设计? 2.范式 2.1.范式简介 2.2.范式都包括哪些 2.3.键和相关属性的概念 2.4.第一范式 (1NF) 2.5.第二范式 (2NF) 2.6.第三范式 (3NF ...

最新文章

  1. BZOJ 2132 圈地计划(最小割)【BZOJ 修复工程】
  2. 总结网站调用Flash的几种方法【转】
  3. clover写入efi_2014 黑苹果折腾之clover efi全新安装
  4. 基于Spring Cloud实现微服务前后端系统
  5. FFmpeg 和自由软件社区的更新
  6. spss练习数据_SPSS篇——如何在成千上百万个数据中标识重复个案
  7. cad钣金展开插件_钣金高级工考试大小头手工展开图步骤教程
  8. BZOJ 4034 [HAOI2015]T2 树链剖分
  9. 一个历时五天的 Bug,是如何被灭的?
  10. mysql group by order_(Mysql5.7踩坑)Mysql关于同时使用Group by 和Order by问题
  11. 鲁大师2014 v3.75.14.1058 官方版
  12. excel文件被写保护怎么解除_u盘被写保护怎么解除_u盘怎么解除写保护状态
  13. 全国计算机能力挑战赛含金量高吗,大学里,有哪些含金量高,又容易得奖的国家级比赛?...
  14. Ubuntu安装腾讯软件
  15. jDBC连接mysql数据库的5种方式
  16. rtlinux linux实时补丁,(九)RTLinux补丁以及cyclictest
  17. my opencv voyage
  18. Android攻城狮datePicketimePicker
  19. java做简单的缓存缓存
  20. php安装和环境配置

热门文章

  1. python爬虫如何配置动态爬虫代理
  2. Python爬虫框架Scrapy学习笔记
  3. 华为南太无线解决方案部梁旭阳_工业互联网产业联盟网络组走进华为南京研究所技术研讨会顺利召开...
  4. directx 双缓冲 运动 闪烁_24期0利率 | BMW超值福袋开启“双11”购车狂欢节!!
  5. lxml安装_Beautiful Soup的安装和使用
  6. java感谢_这三天看完Java入门第一季和第二季的成果!纪念一下!感谢Java入门的作者!...
  7. MongoDB是什么以及它如何满足您的应用需求
  8. 动态导入ECMAScript模块一文看懂
  9. 习题10-6 递归求Fabonacci数列 (10 分)
  10. C语言中降序qsort通用写法