MYSQL之随机数生成、保留小数位、获取年龄

一、随机数

1.1、rand函数

   RAND() 函数返回 0(包括)和 1(不包括)之间的随机数。

语法如下:

select rand(),rand(),rand();

结果如下:

mysql> select rand(),rand(),rand();
+-------------------+--------------------+--------------------+
| rand()            | rand()             | rand()             |
+-------------------+--------------------+--------------------+
| 0.778827545027088 | 0.4953759373122602 | 0.1403970822136822 |
+-------------------+--------------------+--------------------+
1 row in set (0.00 sec)

1.2、随机整数

  比如生成 [10,100] 的随机数,计算公式为:round(rand() * (m - n) + n)

语法如下:

SELECT round(rand() * (100 - 10) + 10);

结果如下:

mysql> SELECT 
    ->     round(rand() * (100 - 10) + 10) as '随机整数1',
    ->     round(rand() * (100 - 10) + 10) as '随机整数2',
    ->     round(rand() * (100 - 10) + 10) as '随机整数3';
+---------------+---------------+---------------+
| 随机整数1     | 随机整数2     | 随机整数3     |
+---------------+---------------+---------------+
|            45 |            19 |            88 |
+---------------+---------------+---------------+
1 row in set (0.01 sec)

  有些小伙伴可能会用到 floor 函数,在计算闭包区间时,比如生成 [50,200] 的随机数,计算公式为:floor(rand() * (m - n + 1) + n),不要漏掉那个 +1 了,不然你取不到最大值。

语法如下:

SELECT floor(rand() * (200 - 50 + 1) + 50);

1.3、随机小数

  比如生成 [60,100] 范围内的随机小数,计算公式为:round(rand() * (m - n) + n, 2),后面的数字 2 就是保留几位小数。

语法如下:

SELECT round(rand() * (100 - 60) + 60, 2);

结果如下:

mysql> SELECT 
    ->     round(rand() * (100 - 60) + 60, 2) as '随机数1',
    ->     round(rand() * (100 - 60) + 60, 2) as '随机数2',
    ->     round(rand() * (100 - 60) + 60, 2) as '随机数3';
+------------+------------+------------+
| 随机数1    | 随机数2     | 随机数3    |
+------------+------------+------------+
|      60.10 |      99.76 |      98.52 |
+------------+------------+------------+
1 row in set (0.00 sec)

1.4、更新随机值

  比如随机给优惠券金额生成 [5,10] 范围内的随机小数

UPDATE tb_inf_coupon set freeAmount=round(rand() * (10 - 5) + 5);

二、保留小数位

假设我们有们的表数据如下:

mysql> select total_amount,pay_amount,free_amount from tb_coupon;
+--------------+------------+-------------+
| total_amount | pay_amount | free_amount |
+--------------+------------+-------------+
|     10086.21 |       1000 |       86.21 |
|       520.98 |      50000 |       20.98 |
|        19.88 |       1900 |        0.88 |
+--------------+------------+-------------+
3 rows in set (0.00 sec)

  这里的三个金额

  • total_amount double 型,单位是
  • pay_amount int 型,单位是
  • free_amount decimal 型,单位是

  这里只是为了演示,实际工作中绝对不会这样的,精度不高的情况下都是按分存取,就使用 BigInt 类型,如果精度高的就使用 decimal 类型。

2.1、round函数

查询语句

SELECT 
    round(total_amount, 2) as 'round处理double型',
    round(pay_amount / 100.0, 2) as 'round处理int型',
    round(free_amount, 2) as 'round处理decimal型'
FROM
    tb_coupon;

查询结果

+----------------------+-------------------+-----------------------+
| round处理double型    | round处理int型     | round处理decimal型    |
+----------------------+-------------------+-----------------------+
|             10086.21 |             10.00 |                 86.21 |
|               520.98 |            500.00 |                 20.98 |
|                19.88 |             19.00 |                  0.88 |
+----------------------+-------------------+-----------------------+
3 rows in set (0.00 sec)

2.2、convert函数

查询语句

select 
	convert(total_amount, DECIMAL(10, 2)) as 'convert处理double型',
    convert(pay_amount/100.0, DECIMAL(10, 2)) as 'convert处理int型',
    convert(free_amount, DECIMAL(10, 2)) as 'convert处理decimal型'
from  
	tb_coupon;

查询结果

+------------------------+---------------------+-------------------------+
| convert处理double型    | convert处理int型     | convert处理decimal型    |
+------------------------+---------------------+-------------------------+
|               10086.21 |               10.00 |                   86.21 |
|                 520.98 |              500.00 |                   20.98 |
|                  19.88 |               19.00 |                    0.88 |
+------------------------+---------------------+-------------------------+
3 rows in set (0.00 sec)

2.3、cast函数

查询语句

select 
	cast(total_amount as DECIMAL(10,2)) as 'cast处理double型',
    cast(pay_amount/100.0 as DECIMAL(10,2)) as 'cast处理int型',
    cast(free_amount as DECIMAL(10,2)) as 'cast处理decimal型'
from  
	tb_coupon;

查询结果

+---------------------+------------------+----------------------+
| cast处理double型    | cast处理int型     | cast处理decimal型    |
+---------------------+------------------+----------------------+
|            10086.21 |            10.00 |                86.21 |
|              520.98 |           500.00 |                20.98 |
|               19.88 |            19.00 |                 0.88 |
+---------------------+------------------+----------------------+
3 rows in set (0.00 sec)

2.4、format函数

查询语句

select 
	format(total_amount, 2) as 'format处理double型',
    format(pay_amount/100.0, 2) as 'format处理int型',
    format(free_amount, 2) as 'format处理decimal型'
from  
	tb_coupon;  

查询结果

+-----------------------+--------------------+------------------------+
| format处理double型    | format处理int型    | format处理decimal型    |
+-----------------------+--------------------+------------------------+
| 10,086.21             | 10.00              | 86.21                  |
| 520.98                | 500.00             | 20.98                  |
| 19.88                 | 19.00              | 0.88                   |
+-----------------------+--------------------+------------------------+
3 rows in set (0.00 sec)

  从上面的结果我们可以看到当位数超过3位时就会以 逗号 分隔,并且返回的结果是string类型的,所以我们可以优化下,使用 REPLACE 函数把逗号替换为空。

优化查询语句

select 
	REPLACE(format(total_amount, 2),',','') as '优化format处理double型',
	REPLACE(format(pay_amount/100.0, 2),',','') as '优化format处理int型',
	REPLACE(format(free_amount, 2),',','') as '优化format处理decimal型'
from  
	tb_coupon;    

查询结果

+-----------------------------+--------------------------+------------------------------+
| 优化format处理double型       | 优化format处理int型      | 优化format处理decimal型      |
+-----------------------------+--------------------------+------------------------------+
| 10086.21                    | 10.00                    | 86.21                        |
| 520.98                      | 500.00                   | 20.98                        |
| 19.88                       | 19.00                    | 0.88                         |
+-----------------------------+--------------------------+------------------------------+
3 rows in set (0.00 sec)

三、获取年龄

  假设我们有们的表数据如下,先算出他们的年龄。

mysql> SELECT user_code,user_name,birthday FROM tb_student WHERE user_code BETWEEN 6070 AND 6072;
+-----------+-----------+------------+
| user_code | user_name | birthday   |
+-----------+-----------+------------+
|      6070 | 唐静珊    | 2010-05-13 |
|      6071 | 吴恬美    | 2009-02-17 |
|      6072 | 谢骊艳    | 2009-07-08 |
+-----------+-----------+------------+
3 rows in set (0.00 sec)

3.1、方法一

查询语句

SELECT 
    user_code,
    user_name,
    birthday,
    YEAR(FROM_DAYS(DATEDIFF(NOW(), birthday))) AS '方法一age'
FROM
    school.tb_student
WHERE
    user_code BETWEEN 6070 AND 6072;

语法解析

  • NOW() :得到当前日期和时间
  • DATEDIFF(NOW(), birthday) :计算当前日期到出生日期的间隔天数 n
  • FROM_DAYS(n) :计算从 0000 年 1 月 1 日开始 n 天后的日期,比如得到: 0012-10-24 0014-01-17 0013-08-29
  • YEAR() :获取到年数,即年龄

查询结果

+-----------+-----------+------------+--------------+
| user_code | user_name | birthday   | 方法一age    |
+-----------+-----------+------------+--------------+
|      6070 | 唐静珊    | 2010-05-13 |           12 |
|      6071 | 吴恬美    | 2009-02-17 |           14 |
|      6072 | 谢骊艳    | 2009-07-08 |           13 |
+-----------+-----------+------------+--------------+
3 rows in set (0.00 sec)

3.2、方法二

查询语句

SELECT 
    user_code,
    user_name,
    birthday,
    DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW()) - TO_DAYS(birthday)),'%Y') + 0 AS '方法二age'
FROM
    school.tb_student
WHERE
    user_code BETWEEN 6070 AND 6072;

语法解析

  • NOW() :得到当前日期和时间
  • TO_DAYS(NOW()) :把当前日期转成距离 0000 年 1 月 1 日的天数 m
  • TO_DAYS(birthday) :把出生日期转成距离 0000 年 1 月 1 日的天数 n
  • FROM_DAYS(m,n) :计算从 0000 年 1 月 1 日开始 m-n 天后的日期 diff ,比如得到: 0012-10-24 0014-01-17 0013-08-29
  • DATE_FORMAT(diff,‘%Y’) :格式化获取年份,比如得到: 0012 0014 0013
  • 加上 0 自动转为数字年龄

查询结果

+-----------+-----------+------------+--------------+
| user_code | user_name | birthday   | 方法二age    |
+-----------+-----------+------------+--------------+
|      6070 | 唐静珊    | 2010-05-13 |           12 |
|      6071 | 吴恬美    | 2009-02-17 |           14 |
|      6072 | 谢骊艳    | 2009-07-08 |           13 |
+-----------+-----------+------------+--------------+
3 rows in set (0.00 sec)

3.3、方法三( 推荐

查询语句

SELECT 
    user_code,
    user_name,
    birthday,
    TIMESTAMPDIFF(YEAR, birthday, CURDATE()) AS '方法三age'
FROM
    school.tb_student
WHERE
    user_code BETWEEN 6070 AND 6072;

语法解析

  • CURDATE() :得到当前日期
  • TIMESTAMPDIFF(YEAR, birthday, CURDATE()) :出生日期和当前日期的年份差值即为年龄

查询结果

+-----------+-----------+------------+--------------+
| user_code | user_name | birthday   | 方法三age    |
+-----------+-----------+------------+--------------+
|      6070 | 唐静珊    | 2010-05-13 |           12 |
|      6071 | 吴恬美    | 2009-02-17 |           14 |
|      6072 | 谢骊艳    | 2009-07-08 |           13 |
+-----------+-----------+------------+--------------+
3 rows in set (0.00 sec)

3.4、方法四

查询语句

SELECT 
    user_code,
    user_name,
    birthday,
    FLOOR(DATEDIFF(CURDATE(), birthday)/365.2422) as '方法四age'
FROM
    school.tb_student
WHERE
    user_code BETWEEN 6070 AND 6072;

语法解析

  • CURDATE() :得到当前日期
  • DATEDIFF(CURDATE(), birthday) :计算当前日期和出生日期的差值整数天 n
  • FLOOR(n/365.2422) :现代人测算得出一年是365.2422日,计算年数后向下取整得到年龄

查询结果

+-----------+-----------+------------+--------------+
| user_code | user_name | birthday   | 方法四age    |
+-----------+-----------+------------+--------------+
|      6070 | 唐静珊    | 2010-05-13 |           12 |
|      6071 | 吴恬美    | 2009-02-17 |           14 |
|      6072 | 谢骊艳    | 2009-07-08 |           13 |
+-----------+-----------+------------+--------------+
3 rows in set (0.00 sec)

四、时间段差异

  • timestampdiff(unit,datetime_expr1,datetime_expr2) 计算时间差,返回 datetime_expr2 − datetime_expr1 的时间差,unit的值可以为:yearmonthdayhourminutesecond

查询语句

SELECT 
    payTime as '支付时间',
    noticeTime as '通知时间',
    timestampdiff(second,payTime,noticeTime) as '时间间隔'
FROM `tb_biz_pay_notice` 
WHERE payTime BETWEEN '2023-03-06 13:30:00' AND '2023-03-06 13:30:05';

查询结果

+---------------------+---------------------+--------------+
| 支付时间            | 通知时间            | 时间间隔     |
+---------------------+---------------------+--------------+
| 2023-03-06 13:30:00 | 2023-03-06 13:30:01 |            1 |
| 2023-03-06 13:30:00 | 2023-03-06 13:30:08 |            8 |
| 2023-03-06 13:30:01 | 2023-03-06 13:30:02 |            1 |
| 2023-03-06 13:30:01 | 2023-03-06 13:30:01 |            0 |
| 2023-03-06 13:30:03 | 2023-03-06 13:30:04 |            1 |
| 2023-03-06 13:30:03 | 2023-03-06 13:30:05 |            2 |
+---------------------+---------------------+--------------+
6 rows in set (0.00 sec)

  一般适合定位两个时间的问题,比如上述有一笔交易支付时间和通知时间差了8秒,就可以去查查是什么原因。或者是用于统计下这些慢通知的比例等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值