MySQL单表查询

前端之家收集整理的这篇文章主要介绍了MySQL单表查询前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、单表查询的语法及关键字执行的优先级

1.1 单表查询语法

  1. SELECT DISTINCT 字段1,字段2... FROM 表名
  2. WHERE 条件
  3. GROUP BY field
  4. HAVING 筛选
  5. ORDER BY field
  6. LIMIT 限制条数

1.2 关键字执行的优先级

  1. from:找到表
  2. where:拿着where指定的约束条件,去文件/表中取出一条条记录
  3. group by:将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组
  4. select:执行select
  5. distinct:去重
  6. having:将分组的结果进行having过滤
  7. order by:将结果按条件排序:order by
  8. limit:限制结果的显示条数
@H_403_98@二、简单查询

2.1 建表和数据准备

  1. company.employee
  2. 员工id id int
  3. 姓名 emp_name varchar
  4. 性别 sex enum
  5. 年龄 age int
  6. 入职日期 hire_date date
  7. 岗位 post varchar
  8. 职位描述 post_comment varchar
  9. 薪水 salary double
  10. 办公室 office int
  11. 部门编号 depart_id int
  12. # 创建表
  13. create table employee(
  14. id int not null unique auto_increment,emp_name varchar(20) not null,sex enum('male','female') not null default 'male',# 大部分是男的
  15. age int(3) unsigned not null default 28,hire_date date not null,post varchar(50),post_comment varchar(100),salary double(15,2),office int,# 一个部门一个屋子
  16. depart_id int
  17. );
  18. # 查看表结构
  19. MysqL> desc employee;
  20. +--------------+-----------------------+------+-----+---------+----------------+
  21. | Field | Type | Null | Key | Default | Extra |
  22. +--------------+-----------------------+------+-----+---------+----------------+
  23. | id | int(11) | NO | PRI | NULL | auto_increment |
  24. | emp_name | varchar(20) | NO | | NULL | |
  25. | sex | enum('male','female') | NO | | male | |
  26. | age | int(3) unsigned | NO | | 28 | |
  27. | hire_date | date | NO | | NULL | |
  28. | post | varchar(50) | YES | | NULL | |
  29. | post_comment | varchar(100) | YES | | NULL | |
  30. | salary | double(15,2) | YES | | NULL | |
  31. | office | int(11) | YES | | NULL | |
  32. | depart_id | int(11) | YES | | NULL | |
  33. +--------------+-----------------------+------+-----+---------+----------------+
  34. # 插入记录
  35. # 三个部门:教学,销售,运营
  36. insert into employee(emp_name,sex,age,hire_date,post,salary,office,depart_id) values
  37. ('nick','male',18,'20170301','老男孩驻上海虹桥最帅',7300.33,401,1),# 以下是教学部
  38. ('jason',78,'20150302','teacher',1000000.31,('sean',81,'20130305',8300,('tank',73,'20140701',3500,('oscar',28,'20121101',2100,('mac','female','20110211',9000,('rocky','19000301',30000,('成龙',48,'20101111',10000,('歪歪','20150311','sale',3000.13,402,# 以下是销售部门
  39. ('丫丫',38,'20101101',2000.35,('丁丁','20110312',1000.37,('星星','20160513',3000.29,('格格','20170127',4000.33,('张野','20160311','operation',10000.13,403,3),# 以下是运营部门
  40. ('程咬金','19970312',20000,('程咬银','20130311',19000,('程咬铜','20150411',18000,('程咬铁','20140512',17000,3)
  41. ;
  42. # ps:如果在windows系统中,插入中文字符,select的结果为空白,可以将所有字符编码统一设置成gbk
  1. # 简单查询
  2. SELECT id,emp_name,post_comment,depart_id
  3. FROM employee;
  4. SELECT * FROM employee;
  5. SELECT emp_name,salary FROM employee;
  6. # 避免重复DISTINCT
  7. SELECT DISTINCT post FROM employee;
  8. # 通过四则运算查询
  9. SELECT emp_name,salary*12 FROM employee;
  10. SELECT emp_name,salary*12 AS Annual_salary FROM employee;
  11. SELECT emp_name,salary*12 Annual_salary FROM employee;
  12. # 定义显示格式
  13. CONCAT() 函数用于连接字符串
  14. SELECT CONCAT('姓名: ',' 年薪: ',salary*12) AS Annual_salary
  15. FROM employee;
  16. CONCAT_WS() 第一个参数为分隔符
  17. SELECT CONCAT_WS(':',salary*12) AS Annual_salary
  18. FROM employee;
  19. 结合CASE语句:
  20. SELECT
  21. (
  22. CASE
  23. WHEN emp_name = 'mac' THEN
  24. emp_name
  25. WHEN emp_name = 'jason' THEN
  26. CONCAT(emp_name,'_BIGSB')
  27. ELSE
  28. concat(emp_name,'SB')
  29. END
  30. ) as new_name
  31. FROM
  32. employee;

2.2 练习

  1. 查出所有员工的名字,薪资,格式为@H_404_114@<名字:nick> <薪资:3000>
  2. 查出所有的岗位(去掉重复)
  3. 查出所有员工名字,以及他们的年薪,年薪的字段名为annual_year
  1. select concat('<名字:','> ','<薪资:','>') from employee;
  2. select distinct depart_id from employee;
  3. select emp_name,salary*12 annual_salary from employee;

三、约束条件(where)

where子句中可以使用:

  1. 比较运算符:> < >= <= <> !=
  2. between 80 and 100 值在80到100之间
  3. in(80,90,100) 值是80或90或100
  4. like 'n%'
    • 通配符可以是%或_,
      • %表示任意多字符
      • _表示一个字符
  5. 逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not
  1. 1. 单条件查询
  2. SELECT emp_name FROM employee
  3. WHERE post='sale';
  4. 2. 多条件查询
  5. SELECT emp_name,salary FROM employee
  6. WHERE post='teacher' AND salary>10000;
  7. 3. 关键字BETWEEN AND
  8. SELECT emp_name,salary FROM employee
  9. WHERE salary BETWEEN 10000 AND 20000;
  10. SELECT emp_name,salary FROM employee
  11. WHERE salary NOT BETWEEN 10000 AND 20000;
  12. 4. 关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS)
  13. SELECT emp_name,post_comment FROM employee
  14. WHERE post_comment IS NULL;
  15. SELECT emp_name,post_comment FROM employee
  16. WHERE post_comment IS NOT NULL;
  17. SELECT emp_name,post_comment FROM employee
  18. WHERE post_comment=''; 注意''是空字符串,不是null
  19. ps
  20. 执行
  21. update employee set post_comment='' where id=2;
  22. 再用上条查看,就会有结果了
  23. 5. 关键字IN集合查询
  24. SELECT emp_name,salary FROM employee
  25. WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ;
  26. SELECT emp_name,salary FROM employee
  27. WHERE salary IN (3000,4000,9000) ;
  28. SELECT emp_name,salary FROM employee
  29. WHERE salary NOT IN (3000,9000) ;
  30. 6. 关键字LIKE模糊查询
  31. 通配符’%’
  32. SELECT * FROM employee
  33. WHERE emp_name LIKE 'ni%';
  34. 通配符’_
  35. SELECT * FROM employee
  36. WHERE emp_name LIKE 'ja__';

3.1 练习

  1. 查看岗位是teacher的员工姓名、年龄
  2. 查看岗位是teacher且年龄大于30岁的员工姓名、年龄
  3. 查看岗位是teacher且薪资在9000-1000范围内的员工姓名、年龄、薪资
  4. 查看岗位描述不为NULL的员工信息
  5. 查看岗位是teacher且薪资是10000或9000或30000的员工姓名、年龄、薪资
  6. 查看岗位是teacher且薪资不是10000或9000或30000的员工姓名、年龄、薪资
  7. 查看岗位是teacher且名字是jin开头的员工姓名、年薪
  1. select emp_name,age from employee where post = 'teacher';
  2. select emp_name,age from employee where post='teacher' and age > 30;
  3. select emp_name,salary from employee where post='teacher' and salary between 9000 and 10000;
  4. select * from employee where post_comment is not null;
  5. select emp_name,salary from employee where post='teacher' and salary in (10000,30000);
  6. select emp_name,salary from employee where post='teacher' and salary not in (10000,salary*12 from employee where post='teacher' and emp_name like 'mac%';

四、分组(group by)

  1. 单独使用GROUP BY关键字分组
  2. SELECT post FROM employee GROUP BY post;
  3. 注意:我们按照post字段分组,那么select查询的字段只能是post,想要获取组内的其他相关信息,需要借助函数
  4. GROUP BY关键字和GROUP_CONCAT()函数一起使用
  5. SELECT post,GROUP_CONCAT(emp_name) FROM employee GROUP BY post; # 按照岗位分组,并查看组内成员名
  6. SELECT post,GROUP_CONCAT(emp_name) as emp_members FROM employee GROUP BY post;
  7. GROUP BY与聚合函数一起使用
  8. select post,count(id) as count from employee group by post; # 按照岗位分组,并查看每个组有多少人

注意:如果我们用unique的字段作为分组的依据,则每一条记录自成一组,这种分组没有意义;多条记录之间的某个字段值相同,该字段通常用来作为分组的依据。

五、聚合函数

强调:聚合函数聚合的是组的内容,若是没有分组,则默认一组。

示例:

  1. SELECT COUNT(*) FROM employee;
  2. SELECT COUNT(*) FROM employee WHERE depart_id=1;
  3. SELECT MAX(salary) FROM employee;
  4. SELECT MIN(salary) FROM employee;
  5. SELECT AVG(salary) FROM employee;
  6. SELECT SUM(salary) FROM employee;
  7. SELECT SUM(salary) FROM employee WHERE depart_id=3;

5.1 练习

  1. 查询岗位名以及岗位包含的所有员工名字
  2. 查询岗位名以及各岗位内包含的员工个数
  3. 查询公司内男员工和女员工的个数
  4. 查询岗位名以及各岗位的平均薪资
  5. 查询岗位名以及各岗位的最高薪资
  6. 查询岗位名以及各岗位的最低薪资
  7. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
  1. 题目1
  2. MysqL> select post,group_concat(emp_name) from employee group by post;
  3. +-----------------------------------------+---------------------------------------------------------+
  4. | post | group_concat(emp_name) |
  5. +-----------------------------------------+---------------------------------------------------------+
  6. | operation | 张野,程咬金,程咬银,程咬铜,程咬铁 |
  7. | sale | 歪歪,丫丫,丁丁,星星,格格 |
  8. | teacher | jason,sean,tank,oscar,mac,rocky,成龙 |
  9. | 老男孩驻上海虹桥最帅 | nick |
  10. +-----------------------------------------+---------------------------------------------------------+
  11. 题目2
  12. MysqL> select post,count(id) from employee group by post;
  13. +-----------------------------------------+-----------+
  14. | post | count(id) |
  15. +-----------------------------------------+-----------+
  16. | operation | 5 |
  17. | sale | 5 |
  18. | teacher | 7 |
  19. | 老男孩驻上海虹桥最帅 | 1 |
  20. +-----------------------------------------+-----------+
  21. 题目3
  22. MysqL> select sex,count(id) from employee group by sex;
  23. +--------+-----------+
  24. | sex | count(id) |
  25. +--------+-----------+
  26. | male | 10 |
  27. | female | 8 |
  28. +--------+-----------+
  29. 题目4
  30. MysqL> select post,avg(salary) from employee group by post;
  31. +-----------------------------------------+---------------+
  32. | post | avg(salary) |
  33. +-----------------------------------------+---------------+
  34. | operation | 16800.026000 |
  35. | sale | 2600.294000 |
  36. | teacher | 151842.901429 |
  37. | 老男孩驻上海虹桥最帅 | 7300.330000 |
  38. +-----------------------------------------+---------------+
  39. 题目5
  40. MysqL> select post,max(salary) from employee group by post;
  41. +-----------------------------------------+-------------+
  42. | post | max(salary) |
  43. +-----------------------------------------+-------------+
  44. | operation | 20000.00 |
  45. | sale | 4000.33 |
  46. | teacher | 1000000.31 |
  47. | 老男孩驻上海虹桥最帅 | 7300.33 |
  48. +-----------------------------------------+-------------+
  49. 题目6
  50. MysqL> select post,min(salary) from employee group by post;
  51. +-----------------------------------------+-------------+
  52. | post | min(salary) |
  53. +-----------------------------------------+-------------+
  54. | operation | 10000.13 |
  55. | sale | 1000.37 |
  56. | teacher | 2100.00 |
  57. | 老男孩驻上海虹桥最帅 | 7300.33 |
  58. +-----------------------------------------+-------------+
  59. 题目7
  60. MysqL> select sex,avg(salary) from employee group by sex;
  61. +--------+---------------+
  62. | sex | avg(salary) |
  63. +--------+---------------+
  64. | male | 110920.077000 |
  65. | female | 7250.183750 |
  66. +--------+---------------+

六、过滤(having)

6.1 where和having的区别

执行优先级从高到低:where > group by > having

  1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数
  2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数

6.1.1 验证

  1. MysqL> select @@sql_mode;
  2. +--------------------+
  3. | @@sql_mode |
  4. +--------------------+
  5. | ONLY_FULL_GROUP_BY |
  6. +--------------------+
  7. row in set (0.00 sec)
  8. MysqL> select * from emp where salary > 100000;
  9. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  10. | id | emp_name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
  11. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  12. | 2 | jason | male | 78 | 2015-03-02 | teacher | NULL | 1000000.31 | 401 | 1 |
  13. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  14. row in set (0.00 sec)
  15. MysqL> select post,group_concat(emp_name) from emp group by post having salary > 10000;#错误,分组后无法直接取到salary字段
  16. ERROR 1054 (42S22): Unknown column 'salary' in 'having clause'
  17. MysqL> select post,group_concat(emp_name) from emp group by post having avg(salary) > 10000;
  18. +-----------+-------------------------------------------------------+
  19. | post | group_concat(emp_name) |
  20. +-----------+-------------------------------------------------------+
  21. | operation | 程咬铁,张野 |
  22. | teacher | 成龙,jason |
  23. +-----------+-------------------------------------------------------+
  24. rows in set (0.00 sec)

6.2 练习

  1. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
  2. 查询各岗位平均薪资大于10000的岗位名、平均工资
  3. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
  1. 题目1
  2. MysqL> select post,group_concat(emp_name),count(id) from employee group by post having count(id) < 2;
  3. +-----------------------------------------+--------------------+-----------+
  4. | post | group_concat(emp_name) | count(id) |
  5. +-----------------------------------------+--------------------+-----------+
  6. | 老男孩驻上海虹桥最帅 | nick | 1 |
  7. +-----------------------------------------+--------------------+-----------+
  8. 题目2
  9. MysqL> select post,avg(salary) from employee group by post having avg(salary) > 10000;
  10. +-----------+---------------+
  11. | post | avg(salary) |
  12. +-----------+---------------+
  13. | operation | 16800.026000 |
  14. | teacher | 151842.901429 |
  15. +-----------+---------------+
  16. 题目3
  17. MysqL> select post,avg(salary) from employee group by post having avg(salary) > 10000 and avg(salary) <20000;
  18. +-----------+--------------+
  19. | post | avg(salary) |
  20. +-----------+--------------+
  21. | operation | 16800.026000 |
  22. +-----------+--------------+

七、查询排序(order by)

  1. 按单列排序
  2. SELECT * FROM employee ORDER BY salary;
  3. SELECT * FROM employee ORDER BY salary ASC;
  4. SELECT * FROM employee ORDER BY salary DESC;
  5. 按多列排序:先按照age排序,如果年纪相同,则按照薪资排序
  6. SELECT * from employee
  7. ORDER BY age,salary DESC;

7.1 练习

  1. 查询所有员工信息,先按照age升序排序,如果age相同则按照hire_date降序排序
  2. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列
  3. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列
  1. 题目1
  2. MysqL> select * from employee ORDER BY age asc,hire_date desc;
  3. 题目2
  4. MysqL> select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) asc;
  5. +-----------+---------------+
  6. | post | avg(salary) |
  7. +-----------+---------------+
  8. | operation | 16800.026000 |
  9. | teacher | 151842.901429 |
  10. +-----------+---------------+
  11. 题目3
  12. MysqL> select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) desc;
  13. +-----------+---------------+
  14. | post | avg(salary) |
  15. +-----------+---------------+
  16. | teacher | 151842.901429 |
  17. | operation | 16800.026000 |
  18. +-----------+---------------+

八、限制查询的记录数(limit)

示例:

  1. SELECT * FROM employee ORDER BY salary DESC
  2. LIMIT 3; #默认初始位置为0
  3. SELECT * FROM employee ORDER BY salary DESC
  4. LIMIT 0,5; #从第0开始,即先出第一条,然后包含这一条在内往后查5条
  5. SELECT * FROM employee ORDER BY salary DESC
  6. LIMIT 5,5; #从第5开始,即先出第6条,然后包含这一条在内往后查5条

8.1 练习

  1. 分页显示,每页5条
  1. MysqL> select * from employee limit 0,5;
  2. +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
  3. | id | emp_name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
  4. +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
  5. | 1 | nick | male | 18 | 2017-03-01 | 老男孩驻上海虹桥最帅 | NULL | 7300.33 | 401 | 1 |
  6. | 2 | jason | male | 78 | 2015-03-02 | teacher | | 1000000.31 | 401 | 1 |
  7. | 3 | sean | male | 81 | 2013-03-05 | teacher | NULL | 8300.00 | 401 | 1 |
  8. | 4 | tank | male | 73 | 2014-07-01 | teacher | NULL | 3500.00 | 401 | 1 |
  9. | 5 | oscar | male | 28 | 2012-11-01 | teacher | NULL | 2100.00 | 401 | 1 |
  10. +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
  11. rows in set (0.00 sec)
  12. MysqL> select * from employee limit 5,5;
  13. +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
  14. | id | emp_name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
  15. +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
  16. | 6 | mac | female | 18 | 2011-02-11 | teacher | NULL | 9000.00 | 401 | 1 |
  17. | 7 | rocky | male | 18 | 1900-03-01 | teacher | NULL | 30000.00 | 401 | 1 |
  18. | 8 | 成龙 | male | 48 | 2010-11-11 | teacher | NULL | 10000.00 | 401 | 1 |
  19. | 9 | 歪歪 | female | 48 | 2015-03-11 | sale | NULL | 3000.13 | 402 | 2 |
  20. | 10 | 丫丫 | female | 38 | 2010-11-01 | sale | NULL | 2000.35 | 402 | 2 |
  21. +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
  22. rows in set (0.00 sec)
  23. MysqL> select * from employee limit 10,5;
  24. +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
  25. | id | emp_name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
  26. +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
  27. | 11 | 丁丁 | female | 18 | 2011-03-12 | sale | NULL | 1000.37 | 402 | 2 |
  28. | 12 | 星星 | female | 18 | 2016-05-13 | sale | NULL | 3000.29 | 402 | 2 |
  29. | 13 | 格格 | female | 28 | 2017-01-27 | sale | NULL | 4000.33 | 402 | 2 |
  30. | 14 | 张野 | male | 28 | 2016-03-11 | operation | NULL | 10000.13 | 403 | 3 |
  31. | 15 | 程咬金 | male | 18 | 1997-03-12 | operation | NULL | 20000.00 | 403 | 3 |
  32. +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
  33. rows in set (0.00 sec)

九、使用正则表达式查询

  1. SELECT * FROM employee WHERE emp_name REGEXP '^jas';
  2. SELECT * FROM employee WHERE emp_name REGEXP 'on$';
  3. SELECT * FROM employee WHERE emp_name REGEXP 'm{2}';
  4. 小结:对字符串匹配的方式
  5. WHERE emp_name = 'nick';
  6. WHERE emp_name LIKE 'sea%';
  7. WHERE emp_name REGEXP 'on$';

9.1 练习

  1. 查看所有员工中名字是mac开头,n或者g结果的员工信息
  1. select * from employee where emp_name regexp '^mac.*[gn]$';

猜你在找的MySQL相关文章