MySQL高阶语句(二)

目录

六.子查询

6.2不同表/多表示例: 

6.3语法:<表达式> [NOT] IN <子查询>

查询分数大于80的记录

子查询还可以用在 INSERT 语句中。子查询的结果集可以通过 INSERT 语句插入到其 他的表中

将t1里的记录全部删除,重新插入info表的记录

UPDATE 语句也可以使用子查询。UPDATE 内的子查询,在 set 更新内容时,可以是单独的一列,也可以是多列。

将caicai的分数改为50

6.4子查询,别名as

七.MySQL视图

 #多表创建视图

 需求:需要创建一个视图,需要输出id、学生姓名、分数以及年龄

 #修改原表数据

 #同时可以通过视图修改原表

八、NULL 值


六.子查询

子查询也被称作内查询或者嵌套查询,是指在一个查询语句里面还嵌套着另一个查询语 句。子查询语句是先于主查询语句被执行的,其结果作为外层的条件返回给主查询进行下一 步的查询过滤。
PS: 子语句可以与主语句所查询的表相同,也可以是不同表

select name,score from info where id in (select id from info where score >80);
                                           嵌套查询
                                           子查询
                                           内连查询
                                           注:最内层的子查询最优先处理

MySQL高阶语句(二)_第1张图片

以上同表示例:

主语句:select name,score from info where id
子语句(集合): select id from info where score >80

PS:子语句中的sql语句是为了,最后过滤出一个结果集,用于主语句的判断条件
⭐⭐ in: 将主表和子表关联/连接的语法

不同表/多表示例:
mysql> create table ky30(id int);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into ky30 values(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from ky30;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

 MySQL高阶语句(二)_第2张图片

6.2不同表/多表示例: 

mysql> create table ky30(id int);
Query OK, 0 rows affected (0.01 sec)

mysql> insert ky29 ky30 values(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
#多表查询
mysql> select id,name,score from ky29 where id in (select * from ky30);
+------+--------+-------+
| id   | name   | score |
+------+--------+-------+
|    1 | liuyi  | 80.00 |
|    2 | wangwu | 90.00 |
|    3 | lisi   | 60.00 |
+------+--------+-------+
3 rows in set (0.00 sec)

 MySQL高阶语句(二)_第3张图片

子查询不仅可以在 SELECT 语句中使用,在 INERT、UPDATE、DELETE 中也同样适用。在嵌套的时候,子查询内部还可以再次嵌套新的子查询,也就是说可以多层嵌套。

(1)语法
IN 用来判断某个值是否在给定的结果集中,通常结合子查询来使用
 

6.3语法:
<表达式> [NOT] IN <子查询>


当表达式与子查询返回的结果集中的某个值相等时,返回 TRUE,否则返回 FALSE。 若启用了 NOT 关键字,则返回值相反。需要注意的是,子查询只能返回一列数据,如果需 求比较复杂,一列解决不了问题,可以使用多层嵌套的方式来应对。 多数情况下,子查询都是与 SELECT 语句一起使用的


查询分数大于80的记录

mysql> select name,score from ky29 where id in (select id from ky29 where score>80);
+----------+-------+
| name     | score |
+----------+-------+
| wangwu   | 90.00 |
| tianqi   | 99.00 |
| jiaoshou | 98.00 |
| lilei    | 11.00 |
+----------+-------+
4 rows in set (0.01 sec)

MySQL高阶语句(二)_第4张图片

子查询还可以用在 INSERT 语句中。子查询的结果集可以通过 INSERT 语句插入到其 他的表中
将t1里的记录全部删除,重新插入info表的记录
 
mysql> insert ky29 t1 select * from ky29 where id in (select id from ky29);
Query OK, 7 rows affected (0.00 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> select * from ky29;                                                  
+----+-----------+-------+----------+-------+
| id | name      | score | address  | hobby |
+----+-----------+-------+----------+-------+
|  1 | shidapeng | 90.00 | nanjing  |  NULL |
|  2 | shangzhen | 80.00 | beijing  |  NULL |
|  3 | tangyan   | 98.00 | shanghai |  NULL |
|  6 | chengu    | 88.00 | nanjing  |  NULL |
|  7 | caicai    | 70.00 | hangzhou |  NULL |
|  8 | zhaokun   | 80.00 | hangzhou |  NULL |
|  9 | xiawenjie | 80.00 | hangzhou |  NULL |
+----+-----------+-------+----------+-------+
7 rows in set (0.00 sec)

MySQL高阶语句(二)_第5张图片

UPDATE 语句也可以使用子查询。UPDATE 内的子查询,在 set 更新内容时,可以是单独的一列,也可以是多列。
将caicai的分数改为50
mysql> update ky29 set score=50 where id in (select * from ky30 where id=2);
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from ky29;
+------+-----------+-------+------------+--------+
| id   | name      | score | address    | hobbid |
+------+-----------+-------+------------+--------+
|    1 | liuyi     | 80.00 | beijing    |      2 |
|    2 | wangwu    | 50.00 | shengzheng |      2 |
|    3 | lisi      | 60.00 | shanghai   |      4 |
|    4 | tianqi    | 99.00 | hangzhou   |      5 |
|    5 | jiaoshou  | 98.00 | laowo      |      3 |
|    6 | hanmeimei | 10.00 | nanjing    |      3 |
|    5 | lilei     | 11.00 | nanjing    |      5 |
+------+-----------+-------+------------+--------+
7 rows in set (0.00 sec)

MySQL高阶语句(二)_第6张图片

update info set score=100 where id not in (select * from member where id >1);
表示 先匹配出member表内的id字段为基础匹配的结果集(2,3)
然后再执行主语句,以主语句的id 为基础 进行where 条件判断/过滤

DELETE 也适用于子查询
删除分数大于80的记录

mysql> delete from ky29 where id in (select id where score>80);
Query OK, 3 rows affected (0.00 sec)

mysql> select id,name,score from ky29;
+----+-----------+-------+
| id | name      | score
+----+-----------+-------+
|  2 | shangzhen | 80.00 |
|  7 | caicai    | 50.00 |
|  8 | zhaokun   | 80.00 |
|  9 | xiawenjie | 80.00 |
+----+-----------+-------+
4 rows in set (0.00 sec)

MySQL高阶语句(二)_第7张图片

在 IN 前面还可以添加 NOT,其作用与IN相反,表示否定(即不在子查询的结果集里面)
删除分数不是大于等于80的记录

mysql> delete from t1 where id not in (select id where score>=80);
Query OK, 1 row affected (0.00 sec)

mysql> select id,name,score from t1;
+----+-----------+-------+
| id | name      | score |
+----+-----------+-------+
|  2 | shangzhen | 80.00 |
|  8 | zhaokun   | 80.00 |
|  9 | xiawenjie | 80.00 |
+----+-----------+-------+
3 rows in set (0.00 sec)

MySQL高阶语句(二)_第8张图片

EXISTS 这个关键字在子查询时,主要用于判断子查询的结果集是否为空。如果不为空, 则返回 TRUE;反之,则返回 FALSE

查询如果存在分数等于80的记录则计算ky29的字段数

mysql> select count(*) from ky29 where exists(select id from ky29 where score=80);
学校里面 (人员信息统计,只有当所有人全部签到之后,在人员信息统计表录入完成侯,我才需要进行统计)
+----------+
| count(*) |
+----------+
|        7 |
+----------+
1 row in set (0.00 sec)

MySQL高阶语句(二)_第9张图片

查询如果存在分数小于50的记录则计算ky29的字段数,ky29表没有小于50的,所以返回0

mysql> select count(*) from info where exists(select id from info where score<50);
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

MySQL高阶语句(二)_第10张图片

6.4子查询,别名as

#查询info表id,name 字段
select id,name from info;
以上命令可以查看到info表的内容


#将结果集做为一张表进行查询的时候,我们也需要用到别名,示例:
需求:从info表中的id和name字段的内容做为"内容" 输出id的部分

mysql> select id from (select id,name from info);
ERROR 1248 (42000): Every derived table must have its own alias

#此时会报错,原因为:
select * from 表名 此为标准格式,而以上的查询语句,"表名"的位置其实是一个完整结果集,mysql并不能直接识别,而此时给与结果集设置一个别名,以”select a.id from a“的方式查询将此结果集视为一张"表",就可以正常查询数据了,如下:

select a.id from (select id,name from info) a;

相当于
select info.id,name from info;
select 表.字段,字段 from 表;

七.MySQL视图

视图:优化操作+安全方案  ⭐⭐
数据库中的虚拟表,这张虚拟表中不包含真实数据,只是做了真实数据的映射
视图可以理解为镜花水月/倒影,动态保存结果集(数据)
基础表info (7行记录) ——》映射(投影)--视图
 

作用场景[图]:
针对不同的人(权限身份),提供不同结果集的“表”(以表格的形式展示)
 

作用范围:
select * from ky29;			#展示的部分是ky29表
select * from view_name;	#展示的一张或多张表

功能:
简化查询结果集、灵活查询、可以针对不同用户呈现不同结果集、相对有更高的安全性
本质而言视图是一种select(结果集的呈现)
PS:视图适合于多表连接浏览时使用!不适合增、删、改
而存储过程适合于使用较频繁的SQL语句,这样可以提高执行效率!

##视图和表的区别和联系

#区别:
①、视图是已经编译好的sql语句。而表不是

②、视图没有实际的物理记录。而表有。
show table status\G

③、表只用物理空间而视图不占用物理空间,视图只是逻辑概念的存在,表可以及时对它进行修改,但视图只能有创建的语句来修改

④、视图是查看数据表的一种方法,可以查询数据表中某些字段构成的数据,只是一些SQL语句的集合。从安全的角度说,视图可以不给用户接触数据表,从而不知道表结构。

⑤、表属于全局模式中的表,是实表;视图属于局部模式的表,是虚表。

⑥、视图的建立和删除只影响视图本身,不影响对应的基本表。(但是更新视图数据,是会影响到基本表的)

#联系:
视图(view)是在基本表之上建立的表,它的结构(即所定义的列)和内容(即所有数据行)都来自基本表,它依据基本表存在而存在。一个视图可以对应一个基本表,也可以对应多个基本表。视图是基本表的抽象和在逻辑意义上建立的新关系。

示例:
需求:满足80分的学生展示在视图中
PS:这个结果会动态变化,同时可以给不同的人群(例如权限范围)

#创建视图(单表)

mysql> create view v_score as select * from ky29 where score>=80;
Query OK, 0 rows affected (0.01 sec)
#查看表状态
show table status\G
#查看视图
mysql> select * from v_score;
+------+-----------+--------+----------+--------+
| id   | name      | score  | address  | hobbid |
+------+-----------+--------+----------+--------+
|    1 | liuyi     | 100.00 | beijing  |      2 |
|    4 | tianqi    | 100.00 | hangzhou |      5 |
|    5 | jiaoshou  | 100.00 | laowo    |      3 |
|    6 | hanmeimei | 100.00 | nanjing  |      3 |
|    7 | lilei     | 100.00 | nanjing  |      5 |
+------+-----------+--------+----------+--------+
#查看视图与源表结构
mysql> desc v_score;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | YES  |     | NULL    |       |
| name    | varchar(10)  | NO   |     | NULL    |       |
| score   | decimal(5,2) | YES  |     | NULL    |       |
| address | varchar(20)  | YES  |     | NULL    |       |
| hobbid  | int(5)       | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
5 rows in set (0.01 sec)

 MySQL高阶语句(二)_第11张图片

 MySQL高阶语句(二)_第12张图片

 #查看视图与源表结构

MySQL高阶语句(二)_第13张图片

mysql> desc ky29;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | YES  |     | NULL    |       |
| name    | varchar(10)  | NO   | PRI | NULL    |       |
| score   | decimal(5,2) | YES  |     | NULL    |       |
| address | varchar(20)  | YES  |     | NULL    |       |
| hobbid  | int(5)       | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

 MySQL高阶语句(二)_第14张图片

 #多表创建视图

创建test01表
create table test01 (id int,name varchar(10),age char(10));
insert into test01 values(1,'zhangsan',20);
insert into test01 values(2,'lisi',30);
insert into test01 values(3,'wangwu',29);

MySQL高阶语句(二)_第15张图片

 需求:需要创建一个视图,需要输出id、学生姓名、分数以及年龄
mysql> create view v_ky29(id,name,score,age) as select ky29.id,ky29.name,ky29.score,test01.age from ky29,test01 where ky29.name=test01.name;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from v_ky29;
+------+--------+-------+------+
| id   | name   | score | age  |
+------+--------+-------+------+
|    3 | lisi   | 60.00 | 30   |
|    2 | wangwu | 90.00 | 29   |
+------+--------+-------+------+
2 rows in set (0.00 sec)

MySQL高阶语句(二)_第16张图片

 #修改原表数据

#修改原表数据
mysql> update ky29 set score='60' where name='liuyi';
Query OK, 1 row affected (1.62 sec)
Rows matched: 1  Changed: 1  Warnings: 0

#查看视图
mysql> select * from v_score;
+------+-----------+--------+----------+--------+
| id   | name      | score  | address  | hobbid |
+------+-----------+--------+----------+--------+
|    4 | tianqi    | 100.00 | hangzhou |      5 |
|    5 | jiaoshou  | 100.00 | laowo    |      3 |
|    6 | hanmeimei | 100.00 | nanjing  |      3 |
|    7 | lilei     | 100.00 | nanjing  |      5 |
+------+-----------+--------+----------+--------+
4 rows in set (0.00 sec)

MySQL高阶语句(二)_第17张图片

 #同时可以通过视图修改原表

mysql> update v_score set score='120' where name='lisi';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from v_score;
+------+-----------+--------+----------+--------+
| id   | name      | score  | address  | hobbid |
+------+-----------+--------+----------+--------+
|    4 | tianqi    | 120.00 | hangzhou |      5 |
|    5 | jiaoshou  | 100.00 | laowo    |      3 |
|    6 | hanmeimei | 100.00 | nanjing  |      3 |
|    7 | lilei     | 100.00 | nanjing  |      5 |
+------+-----------+--------+----------+--------+
4 rows in set (0.00 sec)

MySQL高阶语句(二)_第18张图片MySQL高阶语句(二)_第19张图片

修改表不能修改以函数、复合函数方式计算出来的字段
查询方便、安全性
查询方便:索引速度快、同时可以多表查询更为迅速(视图不保存真实数据,视图本质类似select)
安全性:我们实现登陆的账户是root ——》所拥有权限 ,视图无法显示完整的约束

八、NULL 值

在 SQL 语句使用过程中,经常会碰到 NULL 这几个字符。通常使用 NULL 来表示缺失 的值,也就是在表中该字段是没有值的。如果在创建表时,限制某些字段不为空,则可以使用 NOT NULL 关键字,不使用则默认可以为空。在向表内插入记录或者更新记录时,如果该字段没有 NOT NULL 并且没有值,这时候新记录的该字段将被保存为 NULL。需要注意 的是,NULL 值与数字 0 或者空白(spaces)的字段是不同的,值为 NULL 的字段是没有 值的。在 SQL 语句中,使用 IS NULL 可以判断表内的某个字段是不是 NULL 值,相反的用 IS NOT NULL 可以判断不是 NULL 值。

查询info表结构,name字段是不允许空值的


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

mysql> desc info;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(3)       | NO   | PRI | NULL    | auto_increment |
| name    | varchar(10)  | NO   | UNI | NULL    |                |
| score   | decimal(5,2) | YES  |     | NULL    |                |
| address | varchar(50)  | YES  |     | 未知    |                |
| hobbid  | int(3)       | YES  |     | NULL    |                |
+---------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

MySQL高阶语句(二)_第20张图片

 插入一条记录,分数字段输入null,显示出来就是null

#验证:

alter table info add column addr varchar(50);

update info set addr='nj' where score >=70;

 MySQL高阶语句(二)_第21张图片

 MySQL高阶语句(二)_第22张图片

#统计数量:检测null是否会加入统计中

select count(addr) from ky29;

MySQL高阶语句(二)_第23张图片

 #将ky29表中其中一条数据修改为空值''

update ky29 set addr='' where name='wangwu';

MySQL高阶语句(二)_第24张图片

 #统计数量,检测空值是不会被添加到统计中

select count(addr) from ky29;

MySQL高阶语句(二)_第25张图片

 #查询null值

mysql> select * from ky29 where addr is NULL;
+------+-----------+-------+---------+--------+------+
| id   | name      | score | address | hobbid | addr |
+------+-----------+-------+---------+--------+------+
|    6 | hanmeimei | 10.00 | nanjing |      3 | NULL |
|    7 | lilei     | 11.00 | nanjing |      5 | NULL |
+------+-----------+-------+---------+--------+------+
2 rows in set (0.00 sec)

MySQL高阶语句(二)_第26张图片

 #查询不为空的值

ysql> select * from info where addr is not null;
+------+----------+-------+------------+--------+------+
| id   | name     | score | address    | hobbid | addr |
+------+----------+-------+------------+--------+------+
|    1 | liuyi    | 80.00 | beijing    |      2 | nj   |
|    2 | wangwu   | 90.00 | shengzheng |      2 | nj   |
|    3 | lisi     | 60.00 | shanghai   |      4 |      |
|    4 | tianqi   | 99.00 | hangzhou   |      5 | nj   |
|    5 | jiaoshou | 98.00 | laowo      |      3 | nj   |
|    1 | xiaoer   | 80.00 | hangzhou   |      3 | nj   |
+------+----------+-------+------------+--------+------+
6 rows in set (0.00 sec)

MySQL高阶语句(二)_第27张图片


 

你可能感兴趣的:(mysql,数据库)