Mysql数据库——高阶语句(上)

x33g5p2x  于2021-10-28 转载在 Mysql  
字(12.3k)|赞(0)|评价(0)|浏览(585)

前言

  • 准备模板表
  1. mysql -uroot -p123123
  2. create database puxin;
  3. #创建库
  4. create table xjj (id int(10) primary key not null auto_increment,name varchar(20),score decimal(5,2),address varchar(40),hobby varchar(20));
  5. #创建表
  6. insert into xjj values(1,'liuyi',80,'beijing',2);
  7. insert into xjj values(2,'wangwu',90,'shengzheng',2);
  8. insert into xjj values(3,'lisi',60,'shanghai',4);
  9. insert into xjj values(4,'tianqi',99,'hangzhou',5);
  10. insert into xjj values(5,'jiaoshou',98,'laowo',3);
  11. insert into xjj values(6,'hanmeimei',10,'nanjing',3);
  12. insert into xjj values(7,'lilei',11,'nanjing',5);
  13. insert into xjj values(8,'caicai',16,'nanjing',5);
  14. #插入表
  15. mysql> select * from xjj;
  16. +----+-----------+-------+------------+-------+
  17. | id | name | score | address | hobby |
  18. +----+-----------+-------+------------+-------+
  19. | 1 | liuyi | 80.00 | beijing | 2 |
  20. | 2 | wangwu | 90.00 | shengzheng | 2 |
  21. | 3 | lisi | 60.00 | shanghai | 4 |
  22. | 4 | tianqi | 99.00 | hangzhou | 5 |
  23. | 5 | jiaoshou | 98.00 | laowo | 3 |
  24. | 6 | hanmeimei | 10.00 | nanjing | 3 |
  25. | 7 | lilei | 11.00 | nanjing | 5 |
  26. | 8 | caicai | 16.00 | nanjing | 5 |
  27. +----+-----------+-------+------------+-------+
  28. 8 rows in set (0.00 sec)

常用查询

  • 增、删、改、查
  • 对MySQL数据库的查询,除了基本的查询外,有时候需要对查询的结果集进行处理,例如只取 10 条数据、对查询结果进行排序或分组等等

一、按关键字排序

  • 使用select语句可以将需要的数据从mysql数据库中查询出来,如果对查询的结果进行排序操作,可以使用order by 语句完成排序,并且最终将排序后的结果返回给客户
  • 类比于windows任务管理器
  1. select 字段 from 表名 order by 字段 ASC|DESC

ASC|DESC
ASC是按照升序进行排名的,默认的排序方式,可省略

DESC是按照降序的方式进行排序的
*
order by 也可以通过 where 子语句对查询结果进行进一步的过滤
*
可进行多字段的排序

1.单字段排序

  1. #按分数排序,默认不指定升序排列 asc
  2. mysql> select id,name,score from xjj order by score;
  3. +----+-----------+-------+
  4. | id | name | score |
  5. +----+-----------+-------+
  6. | 6 | hanmeimei | 10.00 |
  7. | 7 | lilei | 11.00 |
  8. | 8 | caicai | 16.00 |
  9. | 3 | lisi | 60.00 |
  10. | 1 | liuyi | 80.00 |
  11. | 2 | wangwu | 90.00 |
  12. | 5 | jiaoshou | 98.00 |
  13. | 4 | tianqi | 99.00 |
  14. +----+-----------+-------+
  15. 8 rows in set (0.00 sec)
  16. #按分数排序,使用desc降序
  17. mysql> select id,name,score from xjj order by score desc;
  18. +----+-----------+-------+
  19. | id | name | score |
  20. +----+-----------+-------+
  21. | 4 | tianqi | 99.00 |
  22. | 5 | jiaoshou | 98.00 |
  23. | 2 | wangwu | 90.00 |
  24. | 1 | liuyi | 80.00 |
  25. | 3 | lisi | 60.00 |
  26. | 8 | caicai | 16.00 |
  27. | 7 | lilei | 11.00 |
  28. | 6 | hanmeimei | 10.00 |
  29. +----+-----------+-------+
  30. 8 rows in set (0.00 sec)

2.条件查询

  1. mysql> select name,score from xjj where address='hangzhou' order by score desc;
  2. +--------+-------+
  3. | name | score |
  4. +--------+-------+
  5. | tianqi | 99.00 |
  6. +--------+-------+
  7. 1 row in set (0.00 sec)

3.多字段排序

  1. #原则:order by之后的参数,使用 “,”分割,优先级是按先后顺序而定
  2. mysql> select id,name,hobby from xjj order by hobby desc,id asc;
  3. +----+-----------+-------+
  4. | id | name | hobby |
  5. +----+-----------+-------+
  6. | 4 | tianqi | 5 |
  7. | 7 | lilei | 5 |
  8. | 8 | caicai | 5 |
  9. | 3 | lisi | 4 |
  10. | 5 | jiaoshou | 3 |
  11. | 6 | hanmeimei | 3 |
  12. | 1 | liuyi | 2 |
  13. | 2 | wangwu | 2 |
  14. +----+-----------+-------+
  15. 8 rows in set (0.00 sec)
  16. 小结:order by之后的第一个参数只有在出现相同的数值,第二个字段才有意思

4.区间判断 AND/OR ——且/或

  1. mysql> select * from xjj where score > 70 and score <=90;
  2. +----+--------+-------+------------+-------+
  3. | id | name | score | address | hobby |
  4. +----+--------+-------+------------+-------+
  5. | 1 | liuyi | 80.00 | beijing | 2 |
  6. | 2 | wangwu | 90.00 | shengzheng | 2 |
  7. +----+--------+-------+------------+-------+
  8. mysql> select * from xjj where score > 70 or score <=90;
  9. +----+-----------+-------+------------+-------+
  10. | id | name | score | address | hobby |
  11. +----+-----------+-------+------------+-------+
  12. | 1 | liuyi | 80.00 | beijing | 2 |
  13. | 2 | wangwu | 90.00 | shengzheng | 2 |
  14. | 3 | lisi | 60.00 | shanghai | 4 |
  15. | 4 | tianqi | 99.00 | hangzhou | 5 |
  16. | 5 | jiaoshou | 98.00 | laowo | 3 |
  17. | 6 | hanmeimei | 10.00 | nanjing | 3 |
  18. | 7 | lilei | 11.00 | nanjing | 5 |
  19. | 8 | caicai | 16.00 | nanjing | 5 |
  20. +----+-----------+-------+------------+-------+
  21. 8 rows in set (0.00 sec)
  22. mysql> select * from xjj where score > 70 or (score <60 and score >15);
  23. +----+----------+-------+------------+-------+
  24. | id | name | score | address | hobby |
  25. +----+----------+-------+------------+-------+
  26. | 1 | liuyi | 80.00 | beijing | 2 |
  27. | 2 | wangwu | 90.00 | shengzheng | 2 |
  28. | 4 | tianqi | 99.00 | hangzhou | 5 |
  29. | 5 | jiaoshou | 98.00 | laowo | 3 |
  30. | 8 | caicai | 16.00 | nanjing | 5 |
  31. +----+----------+-------+------------+-------+
  32. 5 rows in set (0.00 sec)

5.查询不重复记录

  1. select distinct 字段 from 表名;

distinct 必须放在最开头

distinct 只能使用需要去重的字段进行操作

distinct 去重多个字段,含义是:几个字段同时重复时才能被过滤

  1. mysql> select distinct hobby from xjj;
  2. +-------+
  3. | hobby |
  4. +-------+
  5. | 2 |
  6. | 4 |
  7. | 5 |
  8. | 3 |
  9. +-------+
  10. 4 rows in set (0.00 sec)
  11. mysql> select name,hobby from xjj where hobby in (select distinct hobby from xjj);
  12. +-----------+-------+
  13. | name | hobby |
  14. +-----------+-------+
  15. | liuyi | 2 |
  16. | wangwu | 2 |
  17. | lisi | 4 |
  18. | tianqi | 5 |
  19. | jiaoshou | 3 |
  20. | hanmeimei | 3 |
  21. | lilei | 5 |
  22. | caicai | 5 |
  23. +-----------+-------+
  24. 8 rows in set (0.00 sec)

二、对结果进行分组

  • 通过SQL查询出来的结果,还可以对其进行分组,使用group by 语句来实现
  • group by 通常都是结合聚合函数一起使用的,常用的聚合函数包括:计数(count)、求和(sum)、请平均数(avg)、最大值(max)、最小值(min),group by 分组的时候可以按一个或者多个字段对结果进行分组处理
  1. select 字段,聚合函数 from 表名 (where 字段名(匹配) 数值) group by 字段名;
  1. #对xjj进行分组,筛选范围/条件是score大于等于45的 'name',score相同的会默认分在一个组
  2. mysql> select count(name),score from xjj where score>=45 group by score;
  3. +-------------+-------+
  4. | count(name) | score |
  5. +-------------+-------+
  6. | 1 | 60.00 |
  7. | 1 | 80.00 |
  8. | 1 | 90.00 |
  9. | 1 | 98.00 |
  10. | 1 | 99.00 |
  11. +-------------+-------+
  12. 5 rows in set (0.00 sec)
  13. #对xjj表中所有address相同的内容进行分组
  14. mysql> select count(id),address from xjj group by address;
  15. +-----------+------------+
  16. | count(id) | address |
  17. +-----------+------------+
  18. | 1 | beijing |
  19. | 1 | hangzhou |
  20. | 1 | laowo |
  21. | 3 | nanjing |
  22. | 1 | shanghai |
  23. | 1 | shengzheng |
  24. +-----------+------------+
  25. 6 rows in set (0.00 sec)
  26. #基于上一条操作,结合order by把统计的id数量进行按降序序排列
  27. mysql> select count(id), hobby from xjj group by hobby order by count(id)
  28. +-----------+-------+
  29. | count(id) | hobby |
  30. +-----------+-------+
  31. | 3 | 5 |
  32. | 2 | 3 |
  33. | 2 | 2 |
  34. | 1 | 4 |
  35. +-----------+-------+
  36. 4 rows in set (0.00 sec)
  37. #结合where语句,筛选分数大于等于70的分组,计算学生个数按降序排列
  38. mysql> select count(name),score,hobby from xjj where score>=70 group by hobby order by count(name) desc;
  39. +-------------+-------+-------+
  40. | count(name) | score | hobby |
  41. +-------------+-------+-------+
  42. | 2 | 80.00 | 2 |
  43. | 1 | 99.00 | 5 |
  44. | 1 | 98.00 | 3 |
  45. +-------------+-------+-------+
  46. 3 rows in set (0.00 sec)

三、限制结果条目(limit)

  • 在使用mysql select 语句进行查询操作时,结果集返回的是所有匹配的记录,有时候仅需返回第一行或前几行,这时候就需用到limit 子句
  1. select 字段 from 表名 limit [offset,] number
  • LIMIT 的第一个参数是位置偏移量(可选参数),是设置 MySQL 从哪一行开始显示
  • 如果不设定第一个参数,将会从表中的第一条记录开始显示
  • 需要注意的是,第一条记录的 位置偏移量是 0,第二条是 1,以此类推,第二个参数是设置返回记录行的最大数目
  1. #查询所有信息显示前4行记录
  2. mysql> select * from xjj limit 3;
  3. +----+--------+-------+------------+-------+
  4. | id | name | score | address | hobby |
  5. +----+--------+-------+------------+-------+
  6. | 1 | liuyi | 80.00 | beijing | 2 |
  7. | 2 | wangwu | 90.00 | shengzheng | 2 |
  8. | 3 | lisi | 60.00 | shanghai | 4 |
  9. +----+--------+-------+------------+-------+
  10. 3 rows in set (0.00 sec)
  11. #从第4行开始,往后显示3行内容
  12. mysql> select * from xjj limit 3,3;
  13. +----+-----------+-------+----------+-------+
  14. | id | name | score | address | hobby |
  15. +----+-----------+-------+----------+-------+
  16. | 4 | tianqi | 99.00 | hangzhou | 5 |
  17. | 5 | jiaoshou | 98.00 | laowo | 3 |
  18. | 6 | hanmeimei | 10.00 | nanjing | 3 |
  19. +----+-----------+-------+----------+-------+
  20. 3 rows in set (0.00 sec)
  21. #结合order by语句,按id的大小升序排列显示前三行
  22. mysql> select id,name from xjj order by id limit 3;
  23. +----+--------+
  24. | id | name |
  25. +----+--------+
  26. | 1 | liuyi |
  27. | 2 | wangwu |
  28. | 3 | lisi |
  29. +----+--------+
  30. 3 rows in set (0.00 sec)
  31. #输出最后三行
  32. mysql> select id,name from xjj order by id desc limit 3;
  33. +----+-----------+
  34. | id | name |
  35. +----+-----------+
  36. | 8 | caicai |
  37. | 7 | lilei |
  38. | 6 | hanmeimei |
  39. +----+-----------+
  40. 3 rows in set (0.00 sec)

四、设置别名(alias——>as)

  • 在mysql查询时,当表的名字比较长或者表内某些字段比较长时,为了方便书写或者多次使用相同的表时,可以给字段列或表设置别名
  • 方便操作,增强可读性
  1. 列的别名
  2. select 字段 as 字段别名 表名
  3. 表的别名
  4. select 字段 from 表名 as 别名
  5. as 可以省略
  1. #列别名设置示例:
  2. mysql> select name as 姓名,score as 成绩 from xjj;
  3. +-----------+--------+
  4. | 姓名 | 成绩 |
  5. +-----------+--------+
  6. | liuyi | 80.00 |
  7. | wangwu | 90.00 |
  8. | lisi | 60.00 |
  9. | tianqi | 99.00 |
  10. | jiaoshou | 98.00 |
  11. | hanmeimei | 10.00 |
  12. | lilei | 11.00 |
  13. | caicai | 16.00 |
  14. +-----------+--------+
  15. 8 rows in set (0.00 sec)
  16. #不用as也可以,一样显示
  17. mysql> select count(*) number from xjj;
  18. +--------+
  19. | number |
  20. +--------+
  21. | 8 |
  22. +--------+
  23. 1 row in set (0.00 sec)

使用场景

对复杂的表进行查询的时候,别名可以缩短查询语句

多表相连查询的时候(通俗易懂、简短SQL语句)

  1. 此外,AS 还可以作为连接语句的操作符
  2. 创建yyy表,将xjj表的查询记录全部插入yyy
  3. mysql> create table yyy as select * from xjj;
  4. #此处AS起到的作用:
  5. 1、创建了一个新表yyy 并定义表结构,插入表数据(与xjj表相同)
  6. 2、但是'约束'没有被完全'复制'过来
  7. #但是如果原表设置了主键,那么附表的:default字段会默认设置一个0
  8. 相似:
  9. #克隆、复制表结构
  10. create table yyy (select * from xjj);
  11. #也可以加入where 语句判断
  12. mysql> create table aaa as select * from xjj where score >=70;
  13. 在为表设置别名时,要保证别名不能与数据库中的其他表的名称冲突
  14. 列的别名是在结果中有显示的,而表的别名在结果中没有显示,只在执行查询时使用

五、通配符

主要用于替换字符串中的部分字符,通过部分字符的匹配将相关结果查询出来
*
通配符都是跟like(模糊查询)一起使用,并协同where自居共同来完成查询任务
*
常用的: %:百分号表示零个、一个或多个字符 _ :下划线表示单个字符

  1. #查询名字是c开头的记录
  2. mysql> select id,name from xjj where name like 'c%';
  3. +----+--------+
  4. | id | name |
  5. +----+--------+
  6. | 8 | caicai |
  7. +----+--------+
  8. 1 row in set (0.00 sec)
  9. #查询名字里是c和i中间有一个字符的记录
  10. mysql> select id,name from xjj where name like 'c_ic_i';
  11. +----+--------+
  12. | id | name |
  13. +----+--------+
  14. | 8 | caicai |
  15. +----+--------+
  16. 1 row in set (0.00 sec)
  17. #查询名字中间有g的记录
  18. mysql> select id,name from xjj where name like '%g%';
  19. +----+--------+
  20. | id | name |
  21. +----+--------+
  22. | 2 | wangwu |
  23. +----+--------+
  24. 1 row in set (0.00 sec)
  25. #通配符“%”和“_”不仅可以单独使用,也可以组合使用
  26. mysql> select id,name from xjj where name like 'w%_';
  27. +----+--------+
  28. | id | name |
  29. +----+--------+
  30. | 2 | wangwu |
  31. +----+--------+
  32. 1 row in set (0.00 sec)

六、子查询

  • 子查询也被称作内查询或嵌套查询,是指一个查询语句里面嵌套着另一个查询语句
  • 子查询语句是先于主查询语句被执行的,其结果作为外层的条件返回给主查询进行下一步的查询过滤
  • PS: 子语句可以与主语句所查询的表相同,也可以是不同表
  1. mysql> select name,score from xjj where id in (select id from xjj where score > 70);
  2. +----------+-------+
  3. | name | score |
  4. +----------+-------+
  5. | liuyi | 80.00 |
  6. | wangwu | 90.00 |
  7. | tianqi | 99.00 |
  8. | jiaoshou | 98.00 |
  9. +----------+-------+
  10. 4 rows in set (0.00 sec)
  11. #主语句:select name,score from info where id
  12. 子语句(集合): select id from info where score >80
  13. PS:子语句中的sql语句是为了,最后过滤出一个结果集,用于主语句的判断条件
  14. in: 将主表和子表关联/连接的语法
  • 子查询不仅可以在select 中使用,在insert、update、delete中同样可以使用
  • 支持多层嵌套
  • in语句是用来判断某个值是否在给定的集合内(结果集),in往往和select搭配使用
  • 可以使用 not in 来进行对结果集取反
  1. mysql> create table ttt(id int(4));
  2. mysql> insert into ttt values(1),(2),(3);
  3. #多表查询
  4. mysql> select id,name,score from xjj where id in (select * from ttt);
  5. +----+--------+-------+
  6. | id | name | score |
  7. +----+--------+-------+
  8. | 1 | liuyi | 80.00 |
  9. | 2 | wangwu | 90.00 |
  10. | 3 | lisi | 60.00 |
  11. +----+--------+-------+
  12. 3 rows in set (0.00 sec)

1.子查询—exists

exists 这个关键字在子查询时,主要用于判断exists之后的条件是否成立,如果成立,则正常执行主语句的匹配,如不成立,则不会执行主语句查询,
如子查询结果集不成立的话,输出为null

count为计数,sum为求和,使用sum求和结合exists,如子查询结果集不成立的话,输出为null

  1. #查询如果存在分数等于80的记录则计算xjj的字段数
  2. mysql> select count(*) from xjj where exists(select id from xjj where score=80);
  3. +----------+
  4. | count(*) |
  5. +----------+
  6. | 8 |
  7. +----------+
  8. 1 row in set (0.00 sec)
  9. #查询如果存在分数小于50的记录则计算xjj的字段数,xjj表没有小于50的,所以返回0
  10. mysql> select count(*) from xjj where exists(select id xjj where score<60);
  11. +----------+
  12. | count(*) |
  13. +----------+
  14. | 3 |
  15. +----------+
  16. 1 row in set (0.01 sec)

2.子查询—as

  1. 例:
  2. select name,hobby from xjj;
  3. 以上命令可以查询一张表的namehobby信息
  4. 将结果作为“表”进行查询的时候,我们也需要用到别名
  5. 比如我们输入:select hobby from (select name,hobby from xjj);
  6. 会报错,因为 select name,hobby from xjj 得到的是一个结果集,而不是表,mysql 是不能识别的
  7. 所以我们需要对结果集设置一个别名,这样mysql就能将结果集视为一张表
  8. mysql> select a.id from (select id,name from xjj) a;
  9. +----+
  10. | id |
  11. +----+
  12. | 1 |
  13. | 2 |
  14. | 3 |
  15. | 4 |
  16. | 5 |
  17. | 6 |
  18. | 7 |
  19. | 8 |
  20. +----+
  21. 8 rows in set (0.00 sec)
  22. 相当于
  23. select xjj.id,name from xjj;
  24. select 表.字段,字段 from 表;

3.视图

  • 视图是从一个或多个表中导出来的表,是一种虚拟存在的表
  • 数据库中只存放了视图的定义,而没有存放视图中的数据,这些数据存放在原来的表中
  • 使用视图查询数据时,数据库系统会从原来的表中取出对应的数据
  • 视图中的数据依赖于原来表中的数据,一旦表中数据发生改变,显示在视图中的数据也会发生改变
  • 数据库中的虚拟表,这张虚拟表中不包含真实数据,只是做了映射
    镜花水月/倒影,动态保存结果集(数据)
    作用:
    1.使操作简单化,可以对经常使用的查询定义一个视图,使用户不必为同样的查询操作指定条件

2.增加数据的安全性,通过视图,用户只能查询和修改指定的数据

3.提高表的逻辑独立性,视图可以屏蔽原有表结构变化带来的影响

  • 使用视图的大部分情况时为了保障数据安全性,提高查询效率
  • 根据筛选条件创建了一张虚拟表,当修改表中数据时,原表中的数据不再满足筛选条件时,视图中的表将不会再显示此数据
  1. 需求:满足80分的学生展示在视图中
  2. PS:这个结果会动态变化,同时可以给不同的人群(例如权限范围)展示不同的视图
  3. #创建视图
  4. create view v_score as select * from info where score>=80;
  5. show table status\G
  6. #查看视图
  7. mysql> select * from v_score;
  8. +----+----------+-------+------------+-------+
  9. | id | name | score | address | hobby |
  10. +----+----------+-------+------------+-------+
  11. | 1 | liuyi | 80.00 | beijing | 2 |
  12. | 2 | wangwu | 90.00 | shengzheng | 2 |
  13. | 4 | tianqi | 99.00 | hangzhou | 5 |
  14. | 5 | jiaoshou | 98.00 | laowo | 3 |
  15. +----+----------+-------+------------+-------+
  16. 4 rows in set (0.00 sec)
  17. #修改原表数据
  18. update info set score='60' where name='wangwu';
  19. #查看视图
  20. mysql> select * from v_score;
  21. +----+----------+-------+----------+-------+
  22. | id | name | score | address | hobby |
  23. +----+----------+-------+----------+-------+
  24. | 1 | liuyi | 80.00 | beijing | 2 |
  25. | 4 | tianqi | 99.00 | hangzhou | 5 |
  26. | 5 | jiaoshou | 98.00 | laowo | 3 |
  27. +----+----------+-------+----------+-------+
  28. 3 rows in set (0.00 sec)

4.NULL值

null值与空值的区别(空气与真空)
null,不占空间
空字符和0,占用空间
is null无法判断空值
空值使用"=“或者”<>"来处理(!=)
count()计算时,NULL会忽略,空值会加入计算

  1. 插入一条记录,分数字段输入null,显示出来就是null
  2. #验证:
  3. alter table xjj add column addr varchar(50);
  4. update xjj set addr='nj' where score >=70;
  5. #统计数量:检测null是否会加入统计中
  6. select count(addr) from xjj;
  7. #将info表中其中一条数据修改为空值''
  8. update xjj set addr='' where name='wangwu';
  9. #统计数量,检测空值是不会被添加到统计中
  10. mysql> select count(addr) from xjj;
  11. +-------------+
  12. | count(addr) |
  13. +-------------+
  14. | 1 |
  15. +-------------+
  16. 1 row in set (0.00 sec)
  17. #查询null值
  18. mysql> select * from xjj where addr is null;
  19. +----+-----------+-------+----------+-------+------+
  20. | id | name | score | address | hobby | addr |
  21. +----+-----------+-------+----------+-------+------+
  22. | 1 | liuyi | 80.00 | beijing | 2 | NULL |
  23. | 3 | lisi | 60.00 | shanghai | 4 | NULL |
  24. | 4 | tianqi | 99.00 | hangzhou | 5 | NULL |
  25. | 5 | jiaoshou | 98.00 | laowo | 3 | NULL |
  26. | 6 | hanmeimei | 10.00 | nanjing | 3 | NULL |
  27. | 7 | lilei | 11.00 | nanjing | 5 | NULL |
  28. | 8 | caicai | 16.00 | nanjing | 5 | NULL |
  29. +----+-----------+-------+----------+-------+------+
  30. #空值数据: select count(*) from YourTable where Your Column Name is null
  31. #查询不为空的值
  32. mysql> select * from xjj where addr is not null;
  33. +----+--------+-------+------------+-------+------+
  34. | id | name | score | address | hobby | addr |
  35. +----+--------+-------+------------+-------+------+
  36. | 2 | wangwu | 60.00 | shengzheng | 2 | |
  37. +----+--------+-------+------------+-------+------+
  38. #非空值数据: select count(*) from YourTable where YourColumnName is not null

相关文章

最新文章

更多