MySQL函数学习

 

常见函数:

进阶4:常见函数
        一、单行函数
        1、字符函数
               concat拼接
               substr截取子串
               upper转换成大写
               lower转换成小写
               trim去前后指定的空格和字符
               ltrim去左边空格
               rtrim去右边空格
               replace替换
               lpad左填充
               rpad右填充
               instr返回子串第一次出现的索引,如果找不到就返回0
               length 获取字节个数
               ifnull 判断是否为空
查看字符集编码show variables like '%char%';
mysql> select concat(upper(last_name),lower(first_name)) from employees;函数可以嵌套函数
mysql> select substr('李莫愁爱上了陆展元',7,3) out_put;索引从1开始,3表示截取长度
+-----------+
| out_put   |
+-----------+
| 陆展元    |
+-----------+
 
mysql> select instr('杨不悔爱上了殷六侠','殷六侠') out_put ;
+---------+
| out_put |
+---------+
|       7 |
+---------+
 
mysql> select (trim('aa' from 'aaaaaaaa   abc aaaaaa ')) as out_put;
+----------------+只会去掉开头和结尾的
| out_put        |
+----------------+
|    abc aaaaaa  |
+----------------+
mysql> select lpad('aa',10,'bb');
+--------------------+
| lpad('aa',10,'bb') |
+--------------------+
| bbbbbbbbaa         |
+--------------------+
mysql> select replace('abcd','ab','ll');
+---------------------------+
| replace('abcd','ab','ll') |
+---------------------------+
| llcd                      |
+---------------------------+
1 row in set (0.00 sec)
        2、数学函数,第二个参数都是小数位数
               round 四舍五入
               rand 随机数
               floor向下取整
               ceil向上取整>=该数的整数
               mod取余
               truncate截断
mysql> select round(-1.55);
+--------------+
| round(-1.55) |
+--------------+
|           -2 |
+--------------+
mysql> select round(-1.55,1);保留的小数位数
+----------------+
| round(-1.55,1) |
+----------------+
|           -1.6 |
+----------------+
mysql> select ceil(1.01);
+------------+
| ceil(1.01) |
+------------+
|          2 |
+------------+
mysql> select ceil(-1.02);
+-------------+
| ceil(-1.02) |
+-------------+
|          -1 |
+-------------+
mysql> select truncate(-1.02,1);
+-------------------+
| truncate(-1.07,1) |
+-------------------+
|              -1.0 |
+-------------------+
1 row in set (0.00 sec)
 
mysql> select mod(10,-3);
+------------+
| mod(10,-3) |
+------------+
|          1 |
+------------+
1 row in set (0.00 sec)
 
mysql> select mod(-10,-3);
+-------------+
| mod(-10,-3) |
+-------------+
|          -1 |
+-------------+
3、日期函数
               now当前系统日期+时间
               curdate当前系统日期
               curtime当前系统时间
               str_to_date 将字符转换成日期
               date_format将日期转换成字符
        
 
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2018-04-08 13:55:52 |
+---------------------+
1 row in set (0.02 sec)
 
mysql> select curdate();
+------------+
| curdate()  |
+------------+
| 2018-04-08 |
+------------+
1 row in set (0.00 sec)
 
mysql> select curtime();
+-----------+
| curtime() |
+-----------+
| 13:57:08  |
+-----------+
mysql> select year(now());
+-------------+
| year(now()) |
+-------------+
|        2018 |
+-------------+
1 row in set (0.00 sec)
 
mysql> select curtime('1998-1-1');
mysql> select year('1998-1-1');//month
+------------------+
| year('1998-1-1') |
+------------------+
|             1998 |
+------------------+
mysql> select month('1998-1-1');
+-------------------+
| month('1998-1-1') |
+-------------------+
|                 1 |
+-------------------+
1 row in set (0.02 sec)
 
mysql> select monthname('1998-1-1');
+-----------------------+
| monthname('1998-1-1') |
+-----------------------+
| January               |
 
日期字符转换


mysql> select str_to_date('1998-3-2','%Y-%c-%d') as out_put;
+------------+
| out_put    |
+------------+
| 1998-03-02 |
+------------+
mysql> select* from employees where hiredate=str_to_date('4-3 1992','%c-%d %Y');
 
mysql> select date_format(now(),'%Y年%c月%d日') as out_put;
+------------------+
| out_put          |
+------------------+
| 2018年4月08日    |
+------------------+
查询有奖金的员工名和入职日期(XX月/XX日 XX年)
mysql> select last_name,date_format(hiredate,'%c月%d日 %Y年') from employees where commission_pct is not null;
+------------+------------------------------------------+
| last_name  | date_format(hiredate,'%c月%d日 %Y年')    |
+------------+------------------------------------------+
| Russell    | 12月23日 2002年                          |
 
4、流程控制函数
               if 处理双分支
               case语句 处理多分支
               case 判断的字段或表达式
                       when情况1 then语句1
                       when情况2 then语句n
                       …
                       Else 语句n
               end
  mysql> select if(10>5,'大','小') as out_put;
+---------+
| out_put |
+---------+
| 大      |
+---------+
 
mysql> select last_name,commission_pct,if(commission_pct is null,'没奖金,呵呵','有奖金,嘻嘻') from employees out_put;
+-------------+----------------+----------------------------------------------------------------------+
| last_name   | commission_pct | if(commission_pct is null,'没奖金,呵呵','有奖金,嘻嘻')             |
+-------------+----------------+----------------------------------------------------------------------+
| K_ing       |           NULL | 没奖金,呵呵                                                         |
 
查询员工工资,要求
部门号=30,显示工资的1.1倍
部门号=40,显示工资的1.2倍
部门号=50,显示工资的1.3倍
其他部门,显示工资为原工资
mysql> select last_name,department_id,
    -> case department_id
    -> when 30 then salary*1.1
    -> when 40 then salary*1.2
    -> when 50 then salary*1.3
    -> else salary
    -> end as new_salary
-> from employees;
+-------------+----------+---------------+------------+
| last_name   | salary   | department_id | new_salary |
+-------------+----------+---------------+------------+
| K_ing       | 24000.00 |            90 |   24000.00 |
| Kochhar     | 17000.00 |            90 |   17000.00 |
 
 
查询员工工资情况
如果工资>20000,显示A级别
如果工资>15000,显示B级别
如果工资>10000,显示C级别
否则,显示D级别
mysql> select last_name,salary,department_id, case 
when salary>20000 then 'A' 
when salary>15000 then 'B' 
when salary>10000 then 'C' 
else 'D' end as new_salary 
from employees 
order by department_id asc;
+-------------+----------+---------------+------------+
| last_name   | salary   | department_id | new_salary |
+-------------+----------+---------------+------------+
| Grant       |  7000.00 |          NULL | D          |
| Whalen      |  4400.00 |            10 | D          |
| Hartstein   | 13000.00 |            20 | C          |
 
5、其他函数
               version版本
               database当前库
               user当前连接用户
 
二、分组函数,统计,组函数,聚合函数
 
 
               sum 求和
               max 最大值
               min 最小值
               avg 平均值
               count 计数
        
               特点:
               1、以上五个分组函数都忽略null值,除了count(*)
               2、sum和avg一般用于处理数值型
                       max、min、count可以处理任何数据类型
            3、都可以搭配distinct使用,用于统计去重后的结果
               4、count的参数可以支持:
                       字段、*、常量值,一般放1
        
                  建议使用 count(*)

 

mysql> select sum(salary) from employees;

 

+-------------+

 

| sum(salary) |

 

+-------------+

 

|   691400.00 |

 

+-------------+

 

1 row in set (0.00 sec)

 

 

 

mysql> select avg(salary) from employees;

 

+-------------+

 

| avg(salary) |

 

+-------------+

 

| 6461.682243 |

 

+-------------+

 

1 row in set (0.00 sec)

 

 

 

mysql> select min(salary) from employees;

 

+-------------+

 

| min(salary) |

 

+-------------+

 

|     2100.00 |

 

+-------------+

 

1 row in set (0.00 sec)

 

 

 

mysql> select max(salary) from employees;

 

+-------------+

 

| max(salary) |

 

+-------------+

 

|    24000.00 |

 

+-------------+

 

1 row in set (0.00 sec)

 

 

 

mysql> select count(salary) from employees;

 

+---------------+

 

| count(salary) |

 

+---------------+

 

|           107 |

 

+---------------+

 

1 row in set (0.00 sec)

 sumavg一般支持数值型

maxmin支持字符型,能排序的都行

数学的忽略null

可以和distinct搭配去重运算

mysql> select sum(distinct salary),sum(salary) from employees;

+----------------------+-------------+

| sum(distinct salary) | sum(salary) |

+----------------------+-------------+

|            397900.00 |   691400.00 |

+----------------------+-------------+

mysql> select count(*) from employees;

+----------+

| count(*) |

+----------+

|      107 |

+----------+

1 row in set (0.00 sec)

 

mysql> select count(1) from employees;相当于多了一列,都是1,实际也是统计多少行,写2也行

+----------+

| count(1) |

+----------+

|      107 |

+----------+

1 row in set (0.00 sec)

 

和分组函数一起查询有限制:要求是group by

mysql> select avg(salary),employee_id from employees;

ERROR 1140 (42000): In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column 'myemployees.employees.employee_id'; this is incompatible with sql_mode=only_full_group_by

 

查询最大入职时间和最小入职时间相差天数

mysql> select datediff(max(hiredate),min(hiredate)) diffience from employees;

+-----------+

| diffience |

+-----------+

|      8735 |

+-----------+

1 row in set (0.00 sec)

 

查询部门编号为90的员工个数

mysql> select count(*) nums from employees where department_id=90;

+------+

| nums |

+------+

|    3 |

+------+

1 row in set (0.00 sec)

 

进阶5:分组查询
        语法:
        select 查询的字段,分组函数
        from 
        group by 分组的字段
        
        
        特点:
        1、可以按单个字段分组
        2、和分组函数一同查询的字段最好是分组后的字段
        3、分组筛选
                       针对的表       位置                   关键字
        分组前筛选:   原始表         group by的前面         where
        分组后筛选:   分组后的结果集 group by的后面         having
        
        4、可以按多个字段分组,字段之间用逗号隔开
        5、可以支持排序
        6having后可以支持别名

 

查询每个工种最高工资

mysql> select max(salary),job_id from employees group by job_id;

+-------------+------------+

| max(salary) | job_id     |

+-------------+------------+

|     8300.00 | AC_ACCOUNT |

|    12000.00 | AC_MGR     |

|     4400.00 | AD_ASST    |

添加筛选条件

邮箱包含a字符

mysql> select avg(salary),department_id from employees where email like '%a%' group by department_id;

+--------------+---------------+

| avg(salary)  | department_id |

+--------------+---------------+

|  7000.000000 |          NULL |

|  4400.000000 |            10 |

|  9500.000000 |            20 |

|  4460.000000 |            30 |

|  6500.000000 |            40 |

|  3496.153846 |            50 |

|  6200.000000 |            60 |

| 10000.000000 |            70 |

|  8535.294118 |            80 |

| 17000.000000 |            90 |

|  8166.666667 |           100 |

+--------------+---------------+

11 rows in set (0.00 sec)

查询那个部门的员工个数大于2
1.
查询每个部门的员工个数

2.根据1的结果进行筛选

mysql> select count(*),department_id from employees group by department_id;

+----------+---------------+

| count(*) | department_id |

+----------+---------------+

|        1 |          NULL |

|        1 |            10 |

|        2 |            20 |

|        6 |            30 |

+----------+---------------+

12 rows in set (0.01 sec)

Having用于分组后的筛选

mysql> select count(*),department_id from employees group by department_id having count(*)>2;

+----------+---------------+

| count(*) | department_id |

+----------+---------------+

|        6 |            30 |

|       45 |            50 |

 

 

分组前的筛选用where,筛选数据源是原来的表

分组后的筛选用having,筛选数据源是分组后的结果表

分组函数做条件肯定用having,例如最大值大于10的最大值

能用分组前当然用分组前,考虑性能

 

#按表达式或者函数分组

按员工姓名的长度分组,查询每一组的员工个数,并筛选长度大于5

1.     查询每个长度的员工个数

2.     筛选

mysql> select count(*) num,length(last_name) len_name from employees group by len_name having num>5 order by num;

+-----+----------+

| num | len_name |

+-----+----------+

|   7 |        8 |

|   8 |        9 |

 

where后 不支持别名

group by order by支持

orical数据库不支持

 

 

#按多个字段分组

查询每个部门,每个工种的平均工资

mysql> select avg(salary),department_id,job_id from employees group by department_id,job_id;   顺序一样

+--------------+---------------+------------+

| avg(salary)  | department_id | job_id     |

+--------------+---------------+------------+

|  7000.000000 |          NULL | SA_REP     |

sumavg一般支持数值型

maxmin支持字符型,能排序的都行

数学的忽略null

可以和distinct搭配去重运算

mysql> select sum(distinct salary),sum(salary) from employees;

+----------------------+-------------+

| sum(distinct salary) | sum(salary) |

+----------------------+-------------+

|            397900.00 |   691400.00 |

+----------------------+-------------+

mysql> select count(*) from employees;

+----------+

| count(*) |

+----------+

|      107 |

+----------+

1 row in set (0.00 sec)

 

mysql> select count(1) from employees;相当于多了一列,都是1,实际也是统计多少行,写2也行

+----------+

| count(1) |

+----------+

|      107 |

+----------+

1 row in set (0.00 sec)

 

和分组函数一起查询有限制:要求是group by

mysql> select avg(salary),employee_id from employees;

ERROR 1140 (42000): In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column 'myemployees.employees.employee_id'; this is incompatible with sql_mode=only_full_group_by

 

查询最大入职时间和最小入职时间相差天数

mysql> select datediff(max(hiredate),min(hiredate)) diffience from employees;

+-----------+

| diffience |

+-----------+

|      8735 |

+-----------+

1 row in set (0.00 sec)

 

查询部门编号为90的员工个数

mysql> select count(*) nums from employees where department_id=90;

+------+

| nums |

+------+

|    3 |

+------+

1 row in set (0.00 sec)

 

进阶5:分组查询
        语法:
        select 查询的字段,分组函数
        from 
        group by 分组的字段
        
        
        特点:
        1、可以按单个字段分组
        2、和分组函数一同查询的字段最好是分组后的字段
        3、分组筛选
                       针对的表       位置                   关键字
        分组前筛选:   原始表         group by的前面         where
        分组后筛选:   分组后的结果集 group by的后面         having
        
        4、可以按多个字段分组,字段之间用逗号隔开
        5、可以支持排序
        6having后可以支持别名

 

查询每个工种最高工资

mysql> select max(salary),job_id from employees group by job_id;

+-------------+------------+

| max(salary) | job_id     |

+-------------+------------+

|     8300.00 | AC_ACCOUNT |

|    12000.00 | AC_MGR     |

|     4400.00 | AD_ASST    |

添加筛选条件

邮箱包含a字符

mysql> select avg(salary),department_id from employees where email like '%a%' group by department_id;

+--------------+---------------+

| avg(salary)  | department_id |

+--------------+---------------+

|  7000.000000 |          NULL |

|  4400.000000 |            10 |

|  9500.000000 |            20 |

|  4460.000000 |            30 |

|  6500.000000 |            40 |

|  3496.153846 |            50 |

|  6200.000000 |            60 |

| 10000.000000 |            70 |

|  8535.294118 |            80 |

| 17000.000000 |            90 |

|  8166.666667 |           100 |

+--------------+---------------+

11 rows in set (0.00 sec)

查询那个部门的员工个数大于2
1.
查询每个部门的员工个数

2.根据1的结果进行筛选

mysql> select count(*),department_id from employees group by department_id;

+----------+---------------+

| count(*) | department_id |

+----------+---------------+

|        1 |          NULL |

|        1 |            10 |

|        2 |            20 |

|        6 |            30 |

+----------+---------------+

12 rows in set (0.01 sec)

Having用于分组后的筛选

mysql> select count(*),department_id from employees group by department_id having count(*)>2;

+----------+---------------+

| count(*) | department_id |

+----------+---------------+

|        6 |            30 |

|       45 |            50 |

 

 

分组前的筛选用where,筛选数据源是原来的表

分组后的筛选用having,筛选数据源是分组后的结果表

分组函数做条件肯定用having,例如最大值大于10的最大值

能用分组前当然用分组前,考虑性能

 

#按表达式或者函数分组

按员工姓名的长度分组,查询每一组的员工个数,并筛选长度大于5

1.     查询每个长度的员工个数

2.     筛选

mysql> select count(*) num,length(last_name) len_name from employees group by len_name having num>5 order by num;

+-----+----------+

| num | len_name |

+-----+----------+

|   7 |        8 |

|   8 |        9 |

 

where后 不支持别名

group by order by支持

orical数据库不支持

 

 

#按多个字段分组

查询每个部门,每个工种的平均工资

mysql> select avg(salary),department_id,job_id from employees group by department_id,job_id;   顺序一样

+--------------+---------------+------------+

| avg(salary)  | department_id | job_id     |

+--------------+---------------+------------+

|  7000.000000 |          NULL | SA_REP     |

原文地址:https://www.cnblogs.com/BetterThanEver_Victor/p/8744881.html