MySQL必知必会10:数学计算、字符串处理和条件判断

阅读整理自《MySQL 必知必会》- 朱晓峰,详细内容请登录 极客时间 官网购买专栏。

数学函数

主要用来处理数值数据,常用的主要有 3 类,分别是取整函数 ROUND()、CEIL()、FLOOR(),绝对值函数 ABS() 和求余函数 MOD()。

数据准备:

demo.transactiondetail

mysql> select transactionid, itemnumber, quantity, price, discount, salesvalue
    -> from demo.transactiondetails
    -> order by transactionid, itemnumber;
+---------------+------------+----------+-------+----------+------------+
| transactionid | itemnumber | quantity | price | discount | salesvalue |
+---------------+------------+----------+-------+----------+------------+
|             1 |          1 |        2 | 89.00 |     0.99 |     176.22 |
|             1 |          2 |        5 |  5.00 |     0.99 |      24.75 |
|             2 |          1 |        3 | 89.00 |     0.88 |     234.96 |
|             2 |          2 |        6 |  5.00 |     0.88 |      26.40 |
|             3 |          1 |        1 | 89.00 |     0.95 |      84.55 |
|             3 |          2 |       10 |  5.00 |     0.95 |      47.50 |
+---------------+------------+----------+-------+----------+------------+

demo.transacionhead

mysql> select transactionid, transactionno, cashierid, memberid, operatorid, transdate
    -> from demo.transactionhead;
+---------------+------------------+-----------+----------+------------+---------------------+
| transactionid | transactionno    | cashierid | memberid | operatorid | transdate           |
+---------------+------------------+-----------+----------+------------+---------------------+
|             1 | 0120201201000001 |         1 |        1 |          1 | 2020-12-01 00:00:00 |
|             2 | 0120201202000001 |         1 |        2 |          2 | 2020-12-02 00:00:00 |
|             3 | 0120201202000002 |         1 |     NULL |          1 | 2020-12-01 01:00:00 |
+---------------+------------------+-----------+----------+------------+---------------------+

demo.goodsmaster

mysql> select * from demo.goodsmaster;
+------------+---------+-----------+---------------+------+-----------+
| itemnumber | barcode | goodsname | specification | unit | saleprice |
+------------+---------+-----------+---------------+------+-----------+
|          1 | 0001    ||               ||     89.00 |
|          2 | 0002    ||               ||      5.00 |
+------------+---------+-----------+---------------+------+-----------+

demo.membermaster

mysql> select memberid, branchid, cardno, membername, address, phone, pid, memeberpoints, memberdeposit from demo.membermaster;
+----------+----------+----------+------------+---------+-------------+--------------------+---------------+---------------+
| memberid | branchid | cardno   | membername | address | phone       | pid                | memeberpoints | memberdeposit |
+----------+----------+----------+------------+---------+-------------+--------------------+---------------+---------------+
|        1 |        1 | 10000001 | 张三       | 天津    | 13698765432 | 475145197001012356 |          0.00 |          0.00 |
|        2 |        1 | 10000002 | 李四       | 上海    | 18758079161 | 123123199001012356 |          0.00 |          0.00 |
+----------+----------+----------+------------+---------+-------------+--------------------+---------------+---------------+

取整函数

  • 向上取整 ceil(X) 和 ceiling(X):返回大于等于 X 的最小 INT 型整数
  • 向下取整 floor(X):返回小于等于 X 的最大 INT 型整数
  • 舍入函数 round(X,D):X 表示要处理的数,D 表示保留的小数位数,处理的方式是四舍五入,ROUND(X) 表示保留 0 位小数

需求:积分的规则是一元积一分,不满一元不积分,显然是向下取整,那就可以用 FLOOR()函数。

通过关联查询,获得会员消费的相关信息:

mysql> select c.membername as '会员',
    -> b.transactionno as '单号',
    -> b.transdate as '时间',
    -> d.goodsname as '商品名称',
    -> a.salesvalue as '交易金额'
    -> from demo.transactiondetails a
    -> join demo.transactionhead b on (b.transactionid = a.transactionid)
    -> join demo.membermaster c on (c.memberid = b.memberid)
    -> join demo.goodsmaster d on (d.itemnumber = a.itemnumber);
+------+------------------+---------------------+----------+----------+
| 会员 | 单号             | 时间                | 商品名称 | 交易金额 |
+------+------------------+---------------------+----------+----------+
| 张三 | 0120201201000001 | 2020-12-01 00:00:00 ||   176.22 |
| 张三 | 0120201201000001 | 2020-12-01 00:00:00 ||    24.75 |
| 李四 | 0120201202000001 | 2020-12-02 00:00:00 ||   234.96 |
| 李四 | 0120201202000001 | 2020-12-02 00:00:00 ||    26.40 |
+------+------------------+---------------------+----------+----------+

floor(a.salesvalue),对销售金额向下取整,获取会员积分值

select c.membername as '会员',
b.transactionno as '单号',
b.transdate as '时间',
d.goodsname as '商品名称',
floor(a.salesvalue) as '积分'
from demo.transactiondetails a
join demo.transactionhead b on (b.transactionid = a.transactionid)
join demo.membermaster c on (c.memberid = b.memberid)
join demo.goodsmaster d on (d.itemnumber = a.itemnumber);

+------+------------------+---------------------+----------+------+
| 会员 | 单号             | 时间                | 商品名称 | 积分 |
+------+------------------+---------------------+----------+------+
| 张三 | 0120201201000001 | 2020-12-01 00:00:00 ||  176 |
| 张三 | 0120201201000001 | 2020-12-01 00:00:00 ||   24 |
| 李四 | 0120201202000001 | 2020-12-02 00:00:00 ||  234 |
| 李四 | 0120201202000001 | 2020-12-02 00:00:00 ||   26 |
+------+------------------+---------------------+----------+------+

或者:

mysql> select 1.5 - mod(1.5, 1);
+-------------------+
| 1.5 - mod(1.5, 1) |
+-------------------+
|               1.0 |
+-------------------+

mysql> select 1.1 - mod(1.1, 1);
+-------------------+
| 1.1 - mod(1.1, 1) |
+-------------------+
|               1.0 |
+-------------------+

需求:收银的时候,应收金额可以被设定四舍五入到哪一位。比如,可以设定四舍五入到元、到角,或者到分。

mysql> select round(salesvalue, 2)
    -> from demo.transactiondetails where transactionid=1 and itemnumber=1;
+----------------------+
| round(salesvalue, 2) |
+----------------------+
|               176.22 |
+----------------------+

mysql> select round(salesvalue, 1)
    -> from demo.transactiondetails where transactionid=1 and itemnumber=1;
+----------------------+
| round(salesvalue, 1) |
+----------------------+
|                176.2 |
+----------------------+

mysql> select round(salesvalue)
    -> from demo.transactiondetails where transactionid=1 and itemnumber=1;
+-------------------+
| round(salesvalue) |
+-------------------+
|               176 |
+-------------------+

字符串函数

常用的字符串函数有 4 个。

  • concat(s1,s2,…):表示把字符串 s1、s2…… 拼接起来,组成一个字符串
  • cast(表达式 as char):表示将表达式的值转换成字符串
  • char_length(字符串):表示获取字符串的长度
  • space(n):表示获取一个由 n 个空格组成的字符串

需求:完成交易之后,系统必须要打出一张小票。打印小票时,对格式有很多要求。比如说,一张小票纸,57 毫米宽,大概可以打 32 个字符,也就是 16 个汉字。用户要求一条流水打 2 行,第一行是商品信息,第二行要包括数量、价格、折扣和金额 4 种信息。那么,怎么才能清晰地在小票上打印出这些信息,并且打印得整齐漂亮呢?

  1. 打印第一行的商品信息。商品信息包括:商品名称和商品规格,而且商品规格要包含在括号里面。这样就必须把商品名称和商品规格拼接起来,变成一个字符串。

    mysql> select concat(goodsname, '(', specification, ')') as 商品信息
        -> from demo.goodsmaster where itemnumber=1;
    +----------+
    | 商品信息 |
    +----------+
    |(16) |
    +----------+
    
  2. 如何打印第二行。第二行包括数量、价格、折扣和金额,一共是 4 种信息。

    转为字符串

    mysql> select cast(quantity as char)  -- 把数量转换成字符串,把decimal类型转换成字符串
        -> from demo.transactiondetails
        -> where transactionid=1 and itemnumber=1;
    +------------------------+
    | cast(quantity as char) |
    +------------------------+
    | 2                      |
    +------------------------+
    

    计算字符串的长度

    mysql> select char_length(cast(quantity as char)) as 长度
        -> from demo.transactiondetails where transactionid=1 and itemnumber=1;
    +------+
    | 长度 |
    +------+
    |    1 |
    +------+
    

    空格补齐 7 位长度

    mysql> select concat(cast(quantity as char), space(7-char_length(cast(quantity as char)))) as 数量
        -> from demo.transactiondetails where transactionid=1 and itemnumber=1;
    +---------+
    | 数量    |
    +---------+
    | 2       |
    +---------+
    

字符串函数:https://dev.mysql.com/doc/refman/8.0/en/string-functions.html


条件判断函数

条件判断函数的主要作用,就是根据特定的条件返回不同的值,常用的有两种:

  • ifnull(V1, V2):表示如果 V1 的值不为空值,则返回 V1,否则返回 V2
  • if(表达式, V1, V2):如果表达式为真(TRUE),则返回 V1,否则返回 V2
mysql> select goodsname, specification, concat(goodsname, '(', ifnull(specification, ''), ')') as 拼接
    -> from demo.goodsmaster;
+-----------+---------------+----------+
| goodsname | specification | 拼接     |
+-----------+---------------+----------+
|| 16|(16) |
|| NULL          |()     |
+-----------+---------------+----------+
mysql> select goodsname, specification, if(isnull(specification), goodsname, concat(goodsname, '(', ifnull(specification, ''), ')')) as 拼接
    -> from demo.goodsmaster;
+-----------+---------------+----------+
| goodsname | specification | 拼接     |
+-----------+---------------+----------+
|| 16|(16) |
|| NULL          ||  -- 去掉多余的()
+-----------+---------------+----------+

小结

函数 功能
数学计算函数 floor(x): 获取小于等于x的最大整数
ceil(x): 获取大于等于x的最小整数
round(x, d): 通过四舍五入,获得最接近x的,保留d位小数的数值
abs(): 获取x的绝对值
mod(x, y): 获取x被y整除后的余数
concat(s1,s2,…): 连接字符串s1,s2,…
char_length(s): 获取字符串s中的字符的个数,一个汉字算一个字符
字符串函数 space(n): 获取由n个空格组成的字符串
substr() 和 mid(): 获取字符串中的子字符串
trim(): 删除字符串开头两端的子字符串
ltrim(): 删除字符串开头部分的空格
rtrim(): 删除字符串结尾部分的空格
条件判断函数 ifnull(v1, v2): 如果v1为空,返回v2,否则返回v1
if(表达式, v1, v2): 如果表达式为真,返回v1,否则返回v2

函数也有一些坑,比如 round(x) 对x四舍五入后不一定比原来的x大:

mysql> select round(-1.5);
+-------------+
| round(-1.5) |
+-------------+
|          -2 |
+-------------+

mysql> select round(-1.5, 0);
+----------------+
| round(-1.5, 0) |
+----------------+
|             -2 |
+----------------+

mysql> select round(-1.5, 1);
+----------------+
| round(-1.5, 1) |
+----------------+
|           -1.5 |
+----------------+

猜你喜欢

转载自blog.csdn.net/qq_31362767/article/details/123602671