本文主要是介绍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_1
,compare_value_2
等,则CASE
表达式返回相应的结果,即result_1
,result_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_1
,result_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
,FALSE
或NULL
,这三个值之一 -
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
, GOLD
和 SILVER
。
参数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()
函数来解决。如果bizphone
为NULL
,则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 NULL
或IS NOT NULL
。
nullif()函数
- 如果第一个参数等于第二个参数,则返回
NULL
,否则返回第一个参数
语法
NULLIF(expression_1,expression_2);
如果expression_1 = expression_2
为true
,则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')
返回MySQLNULLIF
,因为两个字符串不相等。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高级篇:控制流函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!