zoukankan      html  css  js  c++  java
  • 【MySQL】单表查询

    "


    目录

    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


    "
  • 相关阅读:
    Python基础入门教程
    【前端学习笔记】2015-09-11~~~~ js中ajax请求返回案例
    【前端学习笔记】2015-09-10~~~~ css层叠样式表~~格式
    【前端学习笔记】2015-09-09~~~~nodejs中的require()和module.exports
    【前端学习笔记】2015-09-08~~~~ 关于切图的简单方法
    【前端学习笔记】2015-09-06 ~~~~ setAttribute()、slice()
    【前端学习笔记】2015-09-02 附~~~~~ajax简单请求和获得响应结果
    【前端学习笔记】2015-09-02~~~~ 关于filter()匹配的使用
    【前端学习笔记】2015-09-01 附二 关于jq选择器的简单运用
    【前端学习笔记】2015-09-01 附 split()方法、readyState
  • 原文地址:https://www.cnblogs.com/zyk01/p/11375938.html
Copyright © 2011-2022 走看看