【MySQL】单表查询 -- 2019-08-11 19:25:09

原文: http://106.13.73.98/__/25/

目录

where 约束

group by 分组查询

聚合函数

having 过滤

order by 查询排序

limit 限制查询的记录数



  1. # 语法
  2. select 字段1, 字段2 ... from 表名
  3. where 条件
  4. group by field
  5. having 筛选
  6. order by field
  7. limit 限制条数

重点在于关键字的执行优先级:
from

where

group by

having

select

distinct

order by

limit

1. 找到表:from

2. 拿着where指定的约束条件,去文件(表)中取出一条条记录

3. 将取出的一条条记录进行分组group by,如果没有group by, 则整体作为一组

4. 将分组的结果进行having过滤

5. 执行select

6. 去重

7. 将结果按条件排序:order by

8. 限制结果的显示条数



  1. company.employee
  2. 员工id id int
  3. 姓名 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

  1. # 创建员工表
  2. mysql> create table employee(
  3. -> id int primary key auto_increment,
  4. -> name varchar(20) not null,
  5. -> sex enum(‘male‘, ‘female‘) not null default ‘male‘,
  6. -> age int(3) unsigned not null default 28,
  7. -> hire_date date not null,
  8. -> post varchar(50),
  9. -> post_comment varchar(100),
  10. -> salary double(15, 2),
  11. -> office int,
  12. -> depart_id int
  13. -> );
  14. Query OK, 0 rows affected (0.04 sec)
  15. mysql> desc employee;
  16. +--------------+-----------------------+------+-----+---------+----------------+
  17. | Field | Type | Null | Key | Default | Extra |
  18. +--------------+-----------------------+------+-----+---------+----------------+
  19. | id | int(11) | NO | PRI | NULL | auto_increment |
  20. | name | varchar(20) | NO | | NULL | |
  21. | sex | enum(‘male‘,‘female‘) | NO | | male | |
  22. | age | int(3) unsigned | NO | | 28 | |
  23. | hire_date | date | NO | | NULL | |
  24. | post | varchar(50) | YES | | NULL | |
  25. | post_comment | varchar(100) | YES | | NULL | |
  26. | salary | double(15,2) | YES | | NULL | |
  27. | office | int(11) | YES | | NULL | |
  28. | depart_id | int(11) | YES | | NULL | |
  29. +--------------+-----------------------+------+-----+---------+----------------+
  30. 10 rows in set (0.00 sec)
  31. # 插入记录
  32. # 三个部门:教学,销售,运营
  33. mysql> insert into employee(name ,sex,age,hire_date,post,salary,office,depart_id) values
  34. -> (‘egon‘,‘male‘,18,‘20170301‘,‘老男孩驻沙河办事处外交大使‘,7300.33,401,1),
  35. -> # 以下是教学部
  36. -> (‘alex‘,‘male‘,78,‘20150302‘,‘teacher‘,1000000.31,401,1),
  37. -> (‘wupeiqi‘,‘male‘,81,‘20130305‘,‘teacher‘,8300,401,1),
  38. -> (‘yuanhao‘,‘male‘,73,‘20140701‘,‘teacher‘,3500,401,1),
  39. -> (‘liwenzhou‘,‘male‘,28,‘20121101‘,‘teacher‘,2100,401,1),
  40. -> (‘jingliyang‘,‘female‘,18,‘20110211‘,‘teacher‘,9000,401,1),
  41. -> (‘jinxin‘,‘male‘,18,‘19000301‘,‘teacher‘,30000,401,1),
  42. -> (‘xiaomage‘,‘male‘,48,‘20101111‘,‘teacher‘,10000,401,1),
  43. -> # 以下是销售部
  44. -> (‘歪歪‘,‘female‘,48,‘20150311‘,‘sale‘,3000.13,402,2),
  45. -> (‘丫丫‘,‘female‘,38,‘20101101‘,‘sale‘,2000.35,402,2),
  46. -> (‘丁丁‘,‘female‘,18,‘20110312‘,‘sale‘,1000.37,402,2),
  47. -> (‘星星‘,‘female‘,18,‘20160513‘,‘sale‘,3000.29,402,2),
  48. -> (‘格格‘,‘female‘,28,‘20170127‘,‘sale‘,4000.33,402,2),
  49. -> # 以下是运营部
  50. -> (‘张野‘,‘male‘,28,‘20160311‘,‘operation‘,10000.13,403,3),
  51. -> (‘程咬金‘,‘male‘,18,‘19970312‘,‘operation‘,20000,403,3),
  52. -> (‘程咬银‘,‘female‘,18,‘20130311‘,‘operation‘,19000,403,3),
  53. -> (‘程咬铜‘,‘male‘,18,‘20150411‘,‘operation‘,18000,403,3),
  54. -> (‘程咬铁‘,‘female‘,18,‘20140512‘,‘operation‘,17000,403,3)
  55. -> ;

where 约束

where子句中可以使用:

  1. 比较运算符:>  <  >=  <=  <>  !=
  2. between 80 and 100        # 值在80到100之间
  3. in(80, 90, 100)        # 值是80或90或100
  4. like ‘z%‘ 或 like ‘zy_‘        # %表示任意多字符,_表示任意一个字符
  5. and or not        # 逻辑运算符,在多个条件可以直接使用逻辑运算符

实测:


  1. # 单条件查询
  2. mysql> select id,name from employee where id < 5;
  3. +----+---------+
  4. | id | name |
  5. +----+---------+
  6. | 1 | egon |
  7. | 2 | alex |
  8. | 3 | wupeiqi |
  9. | 4 | yuanhao |
  10. +----+---------+
  11. 4 rows in set (0.00 sec)
  12. # 多条件查询
  13. mysql> select name from employee where post=‘teacher‘ and salary>10000;
  14. +--------+
  15. | name |
  16. +--------+
  17. | alex |
  18. | jinxin |
  19. +--------+
  20. 2 rows in set (0.00 sec)
  21. # 关键字 between and
  22. mysql> select name,salary from employee where salary between 10000 and 20000;
  23. +-----------+----------+
  24. | name | salary |
  25. +-----------+----------+
  26. | xiaomage | 10000.00 |
  27. | 张野 | 10000.13 |
  28. | 程咬金 | 20000.00 |
  29. | 程咬银 | 19000.00 |
  30. | 程咬铜 | 18000.00 |
  31. | 程咬铁 | 17000.00 |
  32. +-----------+----------+
  33. 6 rows in set (0.00 sec)
  34. # 注意:‘‘是空字符串,不是null
  35. mysql> select name,post_comment from employee where post_comment=‘‘;
  36. Empty set (0.00 sec)
  37. # 执行如下代码后再此查询
  38. mysql> update employee set post_comment=‘‘ where id=2;
  39. Query OK, 1 row affected (0.01 sec)
  40. Rows matched: 1 Changed: 1 Warnings: 0
  41. mysql> select name,post_comment from employee where post_comment=‘‘;
  42. +------+--------------+
  43. | name | post_comment |
  44. +------+--------------+
  45. | alex | |
  46. +------+--------------+
  47. 1 row in set (0.00 sec)
  48. # 关键字 in:集合查询
  49. mysql> select name,salary from employee where salary=3000 or salary=3500 or salary=4000 or salary=9000;
  50. +------------+---------+
  51. | name | salary |
  52. +------------+---------+
  53. | yuanhao | 3500.00 |
  54. | jingliyang | 9000.00 |
  55. +------------+---------+
  56. 2 rows in set (0.00 sec)
  57. mysql> select name, salary from employee where salary in(3000, 3500, 4000, 9000);
  58. +------------+---------+
  59. | name | salary |
  60. +------------+---------+
  61. | yuanhao | 3500.00 |
  62. | jingliyang | 9000.00 |
  63. +------------+---------+
  64. 2 rows in set (0.00 sec)
  65. mysql> select name,salary,post from employee where post=‘operation‘ and (salary not in(10000.13));
  66. +-----------+----------+-----------+
  67. | name | salary | post |
  68. +-----------+----------+-----------+
  69. | 程咬金 | 20000.00 | operation |
  70. | 程咬银 | 19000.00 | operation |
  71. | 程咬铜 | 18000.00 | operation |
  72. | 程咬铁 | 17000.00 | operation |
  73. +-----------+----------+-----------+
  74. 4 rows in set (0.00 sec)
  75. # 关键字 link:模糊查询
  76. # 通配符"%":任意多字符
  77. mysql> select * from employee where name like ‘程咬%‘;
  78. +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
  79. | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
  80. +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
  81. | 15 | 程咬金 | male | 18 | 1997-03-12 | operation | NULL | 20000.00 | 403 | 3 |
  82. | 16 | 程咬银 | female | 18 | 2013-03-11 | operation | NULL | 19000.00 | 403 | 3 |
  83. | 17 | 程咬铜 | male | 18 | 2015-04-11 | operation | NULL | 18000.00 | 403 | 3 |
  84. | 18 | 程咬铁 | female | 18 | 2014-05-12 | operation | NULL | 17000.00 | 403 | 3 |
  85. +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
  86. 4 rows in set (0.01 sec)
  87. # 通配符"_":任意单字符
  88. mysql> select * from employee where name like ‘ale_‘;
  89. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  90. | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
  91. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  92. | 2 | alex | male | 78 | 2015-03-02 | teacher | | 1000000.31 | 401 | 1 |
  93. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  94. 1 row in set (0.00 sec)
  95. # 其它查询
  96. 1.查看岗位描述不为NULL的员工信息
  97. select * from employee where post_comment is not null;
  98. 2. 查看岗位是teacher且薪资不是10000或9000或30000的员工姓名、年龄、薪资
  99. select name,age,salary from employee where post=‘teacher‘ and salary not in(10000, 9000, 30000);
  100. 3. 查看岗位是teacher且名字是jin开头的员工姓名、年薪
  101. select name,salary*12 from employee where post=‘teacher‘ and name like ‘jin%‘;

group by 分组查询

1. 首先声明一点:分组发生在where之后,即分组是基于where之后得到的记录而进行的.

2. 分组:将所有记录按照某个相同字段进行归类,比如针对员工信息表的职位分组,或者按照性别分组等.

3. 为何要分组呢?

取每个部门的最高工资

取每个部门的员工数

取男人数和女人数

小窍门:"每" 这个后面的字段,就是我们分组的依据

4. 大前提
可以按照任意字段分组,但是分组完毕后,比如group by post,只能查看post字段,如果想查看组内信息,需要借助于聚合函数.


  1. # 需要设置查询模式:only_full_group_by,如果没有设置,查询的结果默认是组内的第一条记录,没有任何意义
  2. # 如果想分组,必须要设置全局的sql的模式为ONLY_FULL_GROUP_BY
  3. mysql> set global sql_mode=‘ONLY_FULL_GROUP_BY‘;
  4. Query OK, 0 rows affected (0.00 sec)
  5. # 查看MySQL 5.7默认的sql_mode如下:
  6. mysql> select @@global.sql_mode;
  7. +--------------------+
  8. | @@global.sql_mode |
  9. +--------------------+
  10. | ONLY_FULL_GROUP_BY |
  11. +--------------------+
  12. 1 row in set (0.00 sec)
  13. # 设置成功后,一定要退出,然后重新登录方可生效
  14. mysql> exit;
  15. Bye

  1. # 简单示例:根据部门进行分组查询:
  2. mysql> select post from employee group by post;
  3. +-----------------------------------------+
  4. | post |
  5. +-----------------------------------------+
  6. | operation |
  7. | sale |
  8. | teacher |
  9. | 老男孩驻沙河办事处外交大使 |
  10. +-----------------------------------------+
  11. 4 rows in set (0.00 sec)

group by分组之后,只能查看当前字段,如果想查看组内信息,需要借助于聚合函数.


聚合函数

  • max()           # 求最大值
  • min()            # 求最小值
  • avg()            # 求平均值
  • sum()           # 求和
  • count()        # 求总个数
  • group_concat(字段名)        # 拼接

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


  1. # 查每个部门有多少个员工
  2. select post,count(1) from employee group by post; # count(1):"1"的课换成"*"或字段名,好像是新版本上"1"跟"*"的速度基本无差异,
  3. # 查每个部门的平均薪水
  4. select post,avg(salary) from employee group by post;
  5. # 查岗位名以及岗位包含的所有员工名字
  6. select post,group_concat(name) as name from employee group by post; # as name:重命名显示的字段名
  7. # 查公司内男员工和女员工的个数
  8. select sex,count(id) from employee group by sex;
  9. # 查岗位名以及各岗位的最高薪资
  10. select post,max(salary) from employee group by post;
  11. # 查男员工与男员工的平均薪资,女员工与女员工的平均薪资
  12. select sex,avg(salary) from employee group by sex;

having 过滤

  1. 执行优先级从高到低:where > group by > having
  2. where发生在分组group by之前,因而where中可以有任意字段,但是绝对不能使用聚合函数
  3. having发生在分组group by之后,因而having中可以使用分组的字段,无法直接取到其它字段,可使用聚合函数

  1. mysql> select * from employee having salary>100000; # 可能老版本不能直接使用此语法
  2. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  3. | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
  4. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  5. | 2 | alex | male | 78 | 2015-03-02 | teacher | NULL | 1000000.31 | 401 | 1 |
  6. +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
  7. 1 row in set (0.04 sec)
  8. # 住:必须使用group by才能使用group_concat()函数
  9. # 错误,分组后无法直接取到组外的字段
  10. mysql> select post,group_concat(name) from employee group by post having salary > 1000000;
  11. ERROR 1054 (42S22): Unknown column ‘salary‘ in ‘having clause‘

  1. # 示例
  2. 1. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
  3. select post,group_concat(name),count(1) from employee group by post having count(id)<2;
  4. 2. 查询各岗位平均薪资大于10000的岗位名、平均工资
  5. select post,avg(salary) from employee group by post having avg(salary)>10000;
  6. 3. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
  7. select post,avg(salary) from employee group by post having avg(salary)>10000 and avg(salary)<20000;

order by 查询排序

按单列排序:

  • select * from employee order by age;        # 默认升序,根据age升序
  • select * from employee order by age asc;      # asc 升序
  • select * from employee order by age desc;      # desc 降序

按多列排序:

示例:先按照age升序排序,如果年纪相同,则按照id降序
select * from employee order by age asc, id desc;


limit 限制查询的记录数


  1. # 示例
  2. 1. 查询前三行记录
  3. select * from employee limit 3;
  4. 2. 从第0开始,即先查询出第一条,然后包含这一条在内往后查5条
  5. select * from employee order by salary desc limit 0, 5;
  6. 3. 从第5开始,即先查询出第6条,然后包含这一条在内往后查5条
  7. select * from employee order by salary desc limit 5, 5;
  8. 4. 从偏移5开始,往后取10条数据
  9. limit 10 offset 5


原文: http://106.13.73.98/__/25/

原文地址:https://www.cnblogs.com/gqy02/p/11336269.html

时间: 2024-10-03 00:34:19

【MySQL】单表查询 -- 2019-08-11 19:25:09的相关文章

python开发mysql:单表查询&amp;多表查询

一 单表查询,以下是表内容 1 一 having 过滤 2 1.1 having和where 3 select * from emp where id > 15; 4 解析过程;from > where 找到数据 > 分组(没有默认一个组)> select 打印 where是出结果之前 5 select * from emp having id > 15; 6 解析过程;from > where 找到数据(没有约束条件,就是整个表)) > 分组(没有默认一个组)&

0x06 MySQL 单表查询

一 单表查询语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二 关键字执行优先级(重点) 重点中的重点:关键字的执行优先级 1)from 2)where 3)group by 4)having 5)select 6)distinct 7)order by 8)limit 1.找到表:from 2.拿着where指定的约束条件,去文件/表中取出一条条记录 3.将取出的一

mysql 单表查询

目录 单表查询 准备数据 简单查询 比较运算符 范围筛选 between 多选 in 模糊查询 like 逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not 身份运算 - 关于null is null /is not null 正则匹配 regexp 分组 group by 聚合 (把很多行的同一个字段进行一些统计,最终的到一个结果) 分组+聚合 HAVING过滤 单表查询 准备数据 只是把查询结果按照自己想要的方式返回,不对数据做修改 #准备表和记录 company.emplo

133 MySQL单表查询

目录 一.单表查询 1.1 语法 1.2 关键字优先级 1.3 注意(重点) 1.4 测试一个单表的distinct去重 二.表记录查询测试 2.1常用函数 2.2 数据准备 2.3 表记录测试 2.3.1 where条件查询 2.3.2 group by 分组查询 2.3.3 having 和 where 2.3.4 排序 order by 2.3.5 limit限制 一.单表查询 1.1 语法 每次查询出来的一些记录,他们都是一张表,只不过这张表是存在内存中的 查询记录如果想要二次利用的话,

mysql单表查询&amp;&amp;多表查询(职员表14+9)

dept(deptno,dname,loc) emp(empno,ename,job,mgr,hiredate,sal,COMM,deptno) salgrade(grade,losal,hisal) stu(sid,sname,age,gander,province,tuition) 单表查询题目 ==================================================== dept(deptno,dname,loc) emp(empno,ename,job,mgr

python之路--MySQl单表查询

一 单表查询语法 #查询数据的本质:mysql会到你本地的硬盘上找到对应的文件,然后打开文件,按照你的查询条件来找出你需要的数据.下面是完整的一个单表查询的语法 select * from,这个select * 指的是要查询所有字段的数据. SELECT distinct 字段1,字段2... FROM 库名.表名 #from后面是说从库的某个表中去找数据,mysql会去找到这个库对应的文件夹下去找到你表名对应的那个数据文件,找不到就直接报错了,找到了就继续后面的操作 WHERE 条件 #从表中

一个MySQL 单表查询SQL,引起一次“故事”

一.描述故事的过程是这个样子的,MySQL 数据库有一张40多G的大表,开发人员执行了一个单表查询,结果我就收到了一个磁盘空间满的告警.一下子就不淡定了,谁在搞事情,脑海里各种可能行想了一遍,想到的最多的就是ibtmp1爆了,第一时间线上看一下,查到了最大的那个文件,结果和想的一样.这里我们要看SQL是怎么写的,表结构是什么样子,然后和官网对比,MySQL在查询的时候有很多可能会使用磁盘临时表,包括表连接.排序.大字段等等. 二.解决方法临时解决方法:1.临时扩一下硬盘2.直接重启 终结解决方案

MySQL 单表查询(Day42)

阅读目录 一,查询语法 二,简单查询 三,where约束 四,having过滤 五,分组查询 group by 六,关键字的执行优先级 七,查询排列 order by 八,使用聚合函数查询 九,where补充 十,限制查询的记录数:limit ================================================================================================================================

MySQL单表查询之分组查询

分组查询 mysql> select countrycode as total fromCity where id<10; +-------+ | total | +-------+ | AFG  | | AFG  | | AFG  | | AFG  | | NLD  | | NLD  | | NLD  | | NLD  | | NLD  | +-------+ 9 rows in set (0.00 sec) mysql> select countrycode,count(*) ast

mysql单表查询语句优化

Mysql语句优化 范例1:优化语句SELECT * FROM `tbl_order_buy_eta` WHERE `id_order`=1843 #通过explain分析语句结果如下 mysql> explain SELECT * FROM `tbl_order_buy_eta` WHERE `id_order`=1843\G *************************** 1. row ***************************            id: 1   se