数据库

常用函数、分组查询、连接查询

2021-08-04  本文已影响0人  秋天丢了李姑娘

常用函数

分类

SELECT 函数(参数) FROM 表;

函数应用

字符函数实例:

mysql> select length('abc');
+---------------+
| length('abc') |
+---------------+
|             3 |
+---------------+
1 row in set (0.00 sec)


mysql> select length('你好');
+------------------+
| length('你好')   |
+------------------+
|                6 |
+------------------+
1 row in set (0.00 sec)


mysql> select name, email, length(email) from employees where name='李平';
+--------+----------------+---------------+
| name   | email          | length(email) |
+--------+----------------+---------------+
| 李平   | liping@tedu.cn |            14 |
+--------+----------------+---------------+
1 row in set (0.00 sec)
mysql> select char_length('abc');
+--------------------+
| char_length('abc') |
+--------------------+
|                  3 |
+--------------------+
1 row in set (0.00 sec)


mysql> select char_length('你好');
+-----------------------+
| char_length('你好')   |
+-----------------------+
|                     2 |
+-----------------------+
1 row in set (0.00 sec)
// 拼接字符串
mysql> select concat(dept_id, '-', dept_name) from departments;
+---------------------------------+
| concat(dept_id, '-', dept_name) |
+---------------------------------+
| 1-人事部                        |
| 2-财务部                        |
| 3-运维部                        |
| 4-开发部                        |
| 5-测试部                        |
| 6-市场部                        |
| 7-销售部                        |
| 8-法务部                        |
+---------------------------------+
8 rows in set (0.00 sec)
mysql> select name, upper(email) from employees where name like '李%';
+-----------+----------------------+
| name      | upper(email)         |
+-----------+----------------------+
| 李玉英    | LIYUYING@TEDU.CN     |
| 李平      | LIPING@TEDU.CN       |
| 李建华    | LIJIANHUA@TARENA.COM |
| 李莹      | LIYING@TEDU.CN       |
| 李柳      | LILIU@TARENA.COM     |
| 李慧      | LIHUI@TARENA.COM     |
| 李静      | LIJING@TARENA.COM    |
| 李瑞      | LIRUI@TARENA.COM     |
+-----------+----------------------+
8 rows in set (0.00 sec)
// 转小写
mysql> select lower('HelloWorld');
+---------------------+
| lower('HelloWorld') |
+---------------------+
| helloworld          |
+---------------------+
1 row in set (0.00 sec)
mysql> select substr('hello world', 7);
+--------------------------+
| substr('hello world', 7) |
+--------------------------+
| world                    |
+--------------------------+
1 row in set (0.00 sec)


// 取子串,下标从7开始取出3个
mysql> select substr('hello world', 7, 3);
+-----------------------------+
| substr('hello world', 7, 3) |
+-----------------------------+
| wor                         |
+-----------------------------+
1 row in set (0.00 sec)
// 子串在字符串中的位置
mysql> select instr('hello world', 'or');
+----------------------------+
| instr('hello world', 'or') |
+----------------------------+
|                          8 |
+----------------------------+
1 row in set (0.00 sec)


mysql> select instr('hello world', 'ol');
+----------------------------+
| instr('hello world', 'ol') |
+----------------------------+
|                          0 |
+----------------------------+
1 row in set (0.00 sec)
mysql> select trim('  hello world.  ');
+--------------------------+
| trim('  hello world.  ') |
+--------------------------+
| hello world.             |
+--------------------------+
1 row in set (0.00 sec)

数学函数实例

mysql> select abs(-10);
+----------+
| abs(-10) |
+----------+
|       10 |
+----------+
1 row in set (0.00 sec)
mysql> select pi();
+----------+
| pi()     |
+----------+
| 3.141593 |
+----------+
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 ceil(10.1);
+------------+
| ceil(10.1) |
+------------+
|         11 |
+------------+
1 row in set (0.00 sec)
mysql> select floor(10.9);
+-------------+
| floor(10.9) |
+-------------+
|          10 |
+-------------+
1 row in set (0.00 sec)
mysql> select round(10.6666);
+----------------+
| round(10.6666) |
+----------------+
|             11 |
+----------------+
1 row in set (0.00 sec)


mysql> select round(10.6666, 2);
+-------------------+
| round(10.6666, 2) |
+-------------------+
|             10.67 |
+-------------------+
1 row in set (0.00 sec)

日期和时间函数实例

mysql> select curdate();
+------------+
| curdate()  |
+------------+
| 2021-03-09 |
+------------+
1 row in set (0.00 sec)


mysql> select curdate() + 0;
+---------------+
| curdate() + 0 |
+---------------+
|      20210309 |
+---------------+
1 row in set (0.00 sec)
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2021-03-09 02:28:26 |
+---------------------+
1 row in set (0.00 sec)


mysql> select now() + 0;
+----------------+
| now() + 0      |
+----------------+
| 20210309022848 |
+----------------+
1 row in set (0.00 sec)
mysql> select unix_timestamp();
+------------------+
| unix_timestamp() |
+------------------+
|       1615275274 |
+------------------+
1 row in set (0.00 sec)
mysql> select from_unixtime(0);
+---------------------+
| from_unixtime(0)    |
+---------------------+
| 1969-12-31 19:00:00 |
+---------------------+
1 row in set (0.00 sec)
mysql> select month('20211001120000');
+-------------------------+
| month('20211001120000') |
+-------------------------+
|                      10 |
+-------------------------+
1 row in set (0.00 sec)


mysql> select monthname('20211001120000');
+-----------------------------+
| monthname('20211001120000') |
+-----------------------------+
| October                     |
+-----------------------------+
1 row in set (0.00 sec)
mysql> select dayname('20211001120000');
+---------------------------+
| dayname('20211001120000') |
+---------------------------+
| Friday                    |
+---------------------------+
1 row in set (0.00 sec)


mysql> select dayname('20211001');
+---------------------+
| dayname('20211001') |
+---------------------+
| Friday              |
+---------------------+
1 row in set (0.00 sec)
mysql> select week('20211001');
+------------------+
| week('20211001') |
+------------------+
|               39 |
+------------------+
1 row in set (0.00 sec)
mysql> select dayofyear('20211001');
+-----------------------+
| dayofyear('20211001') |
+-----------------------+
|                   274 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select year('20211001');
+------------------+
| year('20211001') |
+------------------+
|             2021 |
+------------------+
1 row in set (0.00 sec)


mysql> select quarter('20211001');
+---------------------+
| quarter('20211001') |
+---------------------+
|                   4 |
+---------------------+
1 row in set (0.00 sec)

流程控制函数实例

mysql> select if(3>0, 'yes', 'no');
+----------------------+
| if(3>0, 'yes', 'no') |
+----------------------+
| yes                  |
+----------------------+
1 row in set (0.00 sec)



mysql> select name, dept_id, if(dept_id=1, '人事部', '非人事部')  from employees where name='张亮';
+--------+---------+--------------------------------------------+
| name   | dept_id | if(dept_id=1, '人事部', '非人事部')        |
+--------+---------+--------------------------------------------+
| 张亮   |       7 | 非人事部                                   |
+--------+---------+--------------------------------------------+
1 row in set (0.00 sec)
mysql> select dept_id, dept_name, ifnull(dept_name, '未设置') from departments;
+---------+-----------+--------------------------------+
| dept_id | dept_name | ifnull(dept_name, '未设置')    |
+---------+-----------+--------------------------------+
|       1 | 人事部    | 人事部                         |
|       2 | 财务部    | 财务部                         |
|       3 | 运维部    | 运维部                         |
|       4 | 开发部    | 开发部                         |
|       5 | 测试部    | 测试部                         |
|       6 | 市场部    | 市场部                         |
|       7 | 销售部    | 销售部                         |
|       8 | 法务部    | 法务部                         |
+---------+-----------+--------------------------------+
8 rows in set (0.00 sec)


mysql> insert into departments(dept_id) values(9);
mysql> select dept_id, dept_name, ifnull(dept_name, '未设置') from departments; 
+---------+-----------+--------------------------------+
| dept_id | dept_name | ifnull(dept_name, '未设置')    |
+---------+-----------+--------------------------------+
|       1 | 人事部    | 人事部                         |
|       2 | 财务部    | 财务部                         |
|       3 | 运维部    | 运维部                         |
|       4 | 开发部    | 开发部                         |
|       5 | 测试部    | 测试部                         |
|       6 | 市场部    | 市场部                         |
|       7 | 销售部    | 销售部                         |
|       8 | 法务部    | 法务部                         |
|       9 | NULL      | 未设置                         |
+---------+-----------+--------------------------------+
9 rows in set (0.00 sec)
mysql> select dept_id, dept_name,
    -> case dept_name
    -> when '运维部' then '技术部门'
    -> when '开发部' then '技术部门'
    -> when '测试部' then '技术部门'
    -> when null then '未设置'
    -> else '非技术部门'
    -> end as '部门类型'
    -> from departments;
+---------+-----------+-----------------+
| dept_id | dept_name | 部门类型        |
+---------+-----------+-----------------+
|       1 | 人事部    | 非技术部门      |
|       2 | 财务部    | 非技术部门      |
|       3 | 运维部    | 技术部门        |
|       4 | 开发部    | 技术部门        |
|       5 | 测试部    | 技术部门        |
|       6 | 市场部    | 非技术部门      |
|       7 | 销售部    | 非技术部门      |
|       8 | 法务部    | 非技术部门      |
|       9 | NULL      | 非技术部门      |
+---------+-----------+-----------------+
9 rows in set (0.00 sec)


mysql> select dept_id, dept_name,
    -> case 
    -> when dept_name='运维部' then '技术部门'
    -> when dept_name='开发部' then '技术部门'
    -> when dept_name='测试部' then '技术部门'
    -> when dept_name is null then '未设置'
    -> else '非技术部门'
    -> end as '部门类型'
    -> from departments;
+---------+-----------+-----------------+
| dept_id | dept_name | 部门类型        |
+---------+-----------+-----------------+
|       1 | 人事部    | 非技术部门      |
|       2 | 财务部    | 非技术部门      |
|       3 | 运维部    | 技术部门        |
|       4 | 开发部    | 技术部门        |
|       5 | 测试部    | 技术部门        |
|       6 | 市场部    | 非技术部门      |
|       7 | 销售部    | 非技术部门      |
|       8 | 法务部    | 非技术部门      |
|       9 | NULL      | 未设置          |
+---------+-----------+-----------------+
9 rows in set (0.00 sec)

分组函数

用于统计,又称为聚合函数或统计函数

mysql> select employee_id, sum(basic+bonus) from salary where employee_id=10 and year(date)=2018;
+-------------+------------------+
| employee_id | sum(basic+bonus) |
+-------------+------------------+
|          10 |           116389 |
+-------------+------------------+
1 row in set (0.00 sec)
mysql> select employee_id, avg(basic+bonus) from salary where employee_id=10 and year(date)=2018;
+-------------+------------------+
| employee_id | avg(basic+bonus) |
+-------------+------------------+
|          10 |       29097.2500 |
+-------------+------------------+
1 row in set (0.00 sec)
mysql> select employee_id, max(basic+bonus) from salary where employee_id=10 and year(date)=2018;
+-------------+------------------+
| employee_id | max(basic+bonus) |
+-------------+------------------+
|          10 |            31837 |
+-------------+------------------+
1 row in set (0.00 sec)
mysql> select employee_id, min(basic+bonus) from salary where employee_id=10 and year(date)=2018;
+-------------+------------------+
| employee_id | min(basic+bonus) |
+-------------+------------------+
|          10 |            24837 |
+-------------+------------------+
1 row in set (0.00 sec)
mysql> select count(*) from departments;
+----------+
| count(*) |
+----------+
|        9 |
+----------+
1 row in set (0.00 sec)

分组查询

语法格式

SELECT 字段名1(要求出现在group by后面),分组函数(),……
FROM 表名
WHERE 条件
GROUP BY 字段名1,字段名2
HAVING 过滤条件
ORDER BY 字段;

应用实例

mysql> select dept_id, count(*) from employees group by dept_id;
+---------+----------+
| dept_id | count(*) |
+---------+----------+
|       1 |        8 |
|       2 |        5 |
|       3 |        6 |
|       4 |       55 |
|       5 |       12 |
|       6 |        9 |
|       7 |       35 |
|       8 |        3 |
+---------+----------+
8 rows in set (0.00 sec)
mysql> select dept_id, min(birth_date) from employees group by dept_id;
+---------+-----------------+
| dept_id | min(birth_date) |
+---------+-----------------+
|       1 | 1971-08-19      |
|       2 | 1971-11-02      |
|       3 | 1971-09-09      |
|       4 | 1972-01-31      |
|       5 | 1971-08-14      |
|       6 | 1973-04-14      |
|       7 | 1971-12-10      |
|       8 | 1989-05-19      |
+---------+-----------------+
8 rows in set (0.00 sec)
mysql> select dept_id, max(hire_date) from employees group by dept_id;
+---------+----------------+
| dept_id | max(hire_date) |
+---------+----------------+
|       1 | 2018-11-21     |
|       2 | 2018-09-03     |
|       3 | 2019-07-04     |
|       4 | 2021-02-04     |
|       5 | 2019-06-08     |
|       6 | 2017-10-07     |
|       7 | 2020-08-21     |
|       8 | 2019-11-14     |
+---------+----------------+
8 rows in set (0.00 sec)
mysql> select dept_id, count(*) from employees where email like '%@tedu.cn' group by dept_id;
+---------+----------+
| dept_id | count(*) |
+---------+----------+
|       1 |        5 |
|       2 |        2 |
|       3 |        4 |
|       4 |       32 |
|       5 |        7 |
|       6 |        5 |
|       7 |       15 |
|       8 |        1 |
+---------+----------+
8 rows in set (0.00 sec)
mysql> select employee_id, sum(basic+bonus) as total from salary where year(date)=2018 group by employee_id order by total desc;
mysql> select dept_id, count(*) from employees where count(*)<10 group by dept_id;
ERROR 1111 (HY000): Invalid use of group function


mysql> select dept_id, count(*) from employees group by dept_id having count(*)<10;
+---------+----------+
| dept_id | count(*) |
+---------+----------+
|       1 |        8 |
|       2 |        5 |
|       3 |        6 |
|       6 |        9 |
|       8 |        3 |
+---------+----------+
5 rows in set (0.00 sec)

连接查询

mysql> select name, dept_name from employees, departments;
mysql> select name, dept_name from employees, departments where employees.dept_id=departments.dept_id;

连接分类

按功能分类

按年代分类

SQL99标准多表查询

SELECT 字段... 
FROM 表1 [AS] 别名 [连接类型]
JOIN 表2 [AS] 别名
ON 连接条件
WHERE 分组前筛选条件
GROUP BY 分组
HAVING 分组后筛选条件
ORDER BY 排序字段

内连接

select 查询列表
from 表1 别名
inner join 表2 别名 on 连接条件
inner join 表3 别名 on 连接条件
[where 筛选条件]
[group by 分组]
[having 分组后筛选]
[order by 排序列表]
等值连接
mysql> select name, dept_name
    -> from employees
    -> inner join departments
    -> on employees.dept_id=departments.dept_id;
mysql> select name, dept_name
    -> from employees as e
    -> inner join departments as d
    -> on e.dept_id=d.dept_id;
mysql> select name, d.dept_id, dept_name
    -> from employees as e
    -> inner join departments as d
    -> on e.dept_id=d.dept_id;
mysql> select name, date, basic+bonus as total
    -> from employees as e
    -> inner join salary as s
    -> on e.employee_id=s.employee_id
    -> where year(s.date)=2018 and e.employee_id=11;
mysql> select name, sum(basic+bonus) from employees
    -> inner join salary
    -> on employees.employee_id=salary.employee_id
    -> where year(salary.date)=2018
    -> group by name;
mysql> select name, sum(basic+bonus) as total from employees as e
    -> inner join salary as s
    -> on e.employee_id=s.employee_id
    -> where year(s.date)=2018
    -> group by name
    -> order by total;
 mysql> select name, sum(basic+bonus) as total from employees as e
    -> inner join salary as s
    -> on e.employee_id=s.employee_id
    -> where year(s.date)=2018
    -> group by name
    -> having total>300000
    -> order by total desc;
非等值连接

创建表语法:

CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
)

创建工资级别表:

mysql> use nsd2021;
mysql> create table wage_grade
-> (
-> id int,
-> grade char(1),
-> low int,
-> high int,
-> primary key (id)
);

向表中插入数据:

INSERT INTO 表名称 VALUES (值1, 值2,....);
mysql> insert into wage_grade values
-> (1, 'A', 5000, 8000),
-> (2, 'B', 8001, 10000),
-> (3, 'C', 10001, 15000),
-> (4, 'D', 15001, 20000),
-> (5, 'E', 20001, 1000000);
mysql> select employee_id, date, basic, grade
    -> from salary as s
    -> inner join wage_grade as g
    -> on s.basic between g.low and g.high
    -> where year(date)=2018 and month(date)=12;
mysql> select grade, count(*)
    -> from salary as s
    -> inner join wage_grade as g
    -> on s.basic between g.low and g.high
    -> where year(date)=2018 and month(date)=12
    -> group by grade;
+-------+----------+
| grade | count(*) |
+-------+----------+
| A     |       13 |
| B     |       12 |
| C     |       30 |
| D     |       32 |
| E     |       33 |
+-------+----------+
5 rows in set (0.00 sec)
mysql> select name, date, basic, grade
    -> from employees as e
    -> inner join salary as s
    -> on e.employee_id=s.employee_id
    -> inner join wage_grade as g
    -> on s.basic between g.low and g.high
    -> where year(date)=2018 and month(date)=12;
自连接
mysql> select e.name, e.hire_date, em.birth_date
    -> from employees as e
    -> inner join employees as em
    -> on month(e.hire_date)=month(em.birth_date)
    -> and e.employee_id=em.employee_id;
+-----------+------------+------------+
| name      | hire_date  | birth_date |
+-----------+------------+------------+
| 李玉英    | 2012-01-19 | 1974-01-25 |
| 郑静      | 2018-02-03 | 1997-02-14 |
| 林刚      | 2007-09-19 | 1990-09-23 |
| 刘桂兰    | 2003-10-14 | 1982-10-11 |
| 张亮      | 2015-08-10 | 1996-08-25 |
| 许欣      | 2011-09-09 | 1982-09-25 |
| 王荣      | 2019-11-14 | 1999-11-22 |
+-----------+------------+------------+
7 rows in set (0.00 sec)

外连接

左外连接
SELECT tb1.字段..., tb2.字段
FROM table1 AS tb1
LEFT OUTER JOIN table2 AS tb2 
ON tb1.字段=tb2.字段
mysql> select d.*, e.name
    -> from departments as d
    -> left outer join employees as e
    -> on d.dept_id=e.dept_id;
右外连接
SELECT tb1.字段..., tb2.字段
FROM table1 AS tb1
RIGHT OUTER JOIN table2 AS tb2 
ON tb1.字段=tb2.字段
mysql> select d.*, e.name
    -> from employees as e
    -> right outer join departments as d
    -> on d.dept_id=e.dept_id;
交叉连接
SELECT <字段名> FROM <表1> CROSS JOIN <表2> [WHERE子句]
mysql> select name, dept_name
    -> from employees
    -> cross join departments;
mysql> grant all on *.* to root@'%' identified by 'NSD2021@tedu.cn';

向部门表中插入数据:

mysql> insert into departments(dept_name) values('采购部');
上一篇 下一篇

猜你喜欢

热点阅读