MySQL高级篇:控制流函数

2024-06-23 02:18

本文主要是介绍MySQL高级篇:控制流函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

控制流函数

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高级篇:控制流函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1086035

相关文章

MySQL MCP 服务器安装配置最佳实践

《MySQLMCP服务器安装配置最佳实践》本文介绍MySQLMCP服务器的安装配置方法,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下... 目录mysql MCP 服务器安装配置指南简介功能特点安装方法数据库配置使用MCP Inspector进行调试开发指

mysql中insert into的基本用法和一些示例

《mysql中insertinto的基本用法和一些示例》INSERTINTO用于向MySQL表插入新行,支持单行/多行及部分列插入,下面给大家介绍mysql中insertinto的基本用法和一些示例... 目录基本语法插入单行数据插入多行数据插入部分列的数据插入默认值注意事项在mysql中,INSERT I

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现