135 MySQL子查询

Wesley13
• 阅读 722

[TOC]

一、子查询的概念

将一条sql语句执行的结果作为另一个sql语句的条件

二、子查询的规则

# 以下是基于对表的增删改查操作的
1.增数据时: insert into 表名 select 子查询   
注解: 对一个表插入数据时,插入的数据可以是另外一个sql语句查询结果,但是首先要创建这个表

2.删除数据时: delete from 表名 条件是 select子查询(表不能与delete表相同)
注解: 删除一个表的某些数据时,他的条件是另一个sql查询语句结果

3.查: select 字段 from 表 条件是select子查询
注解: 查询一个表的数据的条件是一个sql语句的执行结果

4.改: update 表 set 字段=值 条件是select子查询(表不能与update表相同)
注解: 更新一个表的数据,他的条件是另一个sql语句的执行结果

三、子查询的实例

# 数据来源:在单表emp下
# 此处显示emp的数据
mysql> select * from emp;
+----+------+------+------+--------+--------+-----------+-----------+
| id | name | sex  | age  | salary | area   | addr      | dep       |
+----+------+------+------+--------+--------+-----------+-----------+
|  1 | aaa  | 男   |   42 |   10.5 | 上海   | 浦东      | 教职部    |
|  2 | bbb  | 男   |   38 |    9.4 | 山东   | 济南      | 教学部    |
|  3 | ccc  | 女   |   30 |      3 | 江苏   | 张家港    | 教学部    |
|  4 | ddd  | 女   |   28 |    2.4 | 广州   | 广东      | 教学部    |
|  5 | eee  | 男   |   28 |    2.4 | 江苏   | 苏州      | 教学部    |
|  6 | fff  | 男   |   18 |    8.8 | 中国   | 黄浦      | 咨询部    |
|  7 | ggg  | 男   |   18 |    8.8 | 安徽   | 宣城      | 教学部    |
|  8 | hhh  | 男   |   28 |    9.8 | 安徽   | 巢湖      | 教学部    |
|  9 | iii  | 女   |   36 |    1.2 | 安徽   | 芜湖      | 咨询部    |
| 10 | jjj  | 男   |   36 |    5.8 | 山东   | 济南      | 教学部    |
| 11 | kkk  | 女   |   28 |    1.2 | 山东   | 青岛      | 教职部    |
| 12 | lll  | 男   |   30 |      9 | 上海   | 浦东      | 咨询部    |
| 13 | mmm  | 男   |   30 |      6 | 上海   | 浦东      | 咨询部    |
| 14 | nnn  | 男   |   30 |      6 | 上海   | 浦西      | 教学部    |
| 15 | ooo  | 女   |   67 |  2.501 | 上海   | 陆家嘴    | 教学部    |
+----+------+------+------+--------+--------+-----------+-----------+

3.1 案例(基于emp表)

# 题目:每个部门最高薪资的那个人所有信息

1.先创建一个子查询sql(对emp表的部门进行分组,查询每个部门的最高薪资)
select dep,max(salary) from emp group by dep;
mysql> select dep,max(salary) from emp group by dep;
+-----------+-------------+
| dep       | max(salary) |
+-----------+-------------+
| 咨询部    |           9 |
| 教学部    |         9.8 |
| 教职部    |        10.5 |
+-----------+-------------+

2.查操作:通过子查询去进行对emp数据的查找(将子查询作为查询每个部门工资最高的员工的所有信息)
select * from emp where (dep,salary) in (select dep,max(salary) from emp group by dep);
mysql> select * from emp where (dep,salary) in (select dep,max(salary) from emp group by dep);
+----+------+------+------+--------+--------+--------+-----------+
| id | name | sex  | age  | salary | area   | addr   | dep       |
+----+------+------+------+--------+--------+--------+-----------+
|  1 | aaa  | 男   |   42 |   10.5 | 上海   | 浦东   | 教职部    |
|  8 | hhh  | 男   |   28 |    9.8 | 安徽   | 巢湖   | 教学部    |
| 12 | lll  | 男   |   30 |      9 | 上海   | 浦东   | 咨询部    |
+----+------+------+------+--------+--------+--------+-----------+


3.增加数据操作:通过子查询去对一张表进行增加数据操作
    1.首先是先创建一张空表
    create table t1(dep_name varchar(64), max_salary decimal(5,2));
    2.将子查询的结果作为数据添加到t1表里(将子查询的sql语句直接作为t1表的插入数据)
    insert into t1 select dep,max(salary) from emp group by dep;
    mysql> select * from t1;
    +-----------+------------+
    | dep_name  | max_salary |
    +-----------+------------+
    | 咨询部    |       9.00 |
    | 教学部    |       9.80 |
    | 教职部    |      10.50 |
    +-----------+------------+
    3.完成上述题目的需求(查出每个部门中薪资最高的员工的姓名,部门,工资)
    select name,dep_name,salary from emp join t1 on emp.dep=t1.dep_name and 
    emp.salary=t1.max_salary;
    mysql> select name,dep_name,salary from emp join t1 on emp.dep=t1.dep_name and          
    emp.salary=t1.max_salary;
    +------+-----------+--------+
    | name | dep_name  | salary |
    +------+-----------+--------+
    | aaa  | 教职部    |   10.5 |
    | lll  | 咨询部    |      9 |
    +------+-----------+--------+
    
    
4.更新操作:给(update更新的表不能 与 子查询select的表同表)
    1.给每个部门最大薪资+1
    update t1 set max_salary=max_salary+1;
    mysql> select * from t1;
    +-----------+------------+
    | dep_name  | max_salary |
    +-----------+------------+
    | 咨询部    |      10.00 |
    | 教学部    |      10.80 |
    | 教职部    |      11.50 |
    +-----------+------------+
    
    2.给t1额外增加一个新部门
    insert into t1 values ('打杂部', 100);
    mysql> select * from t1;                   );
    +-----------+------------+
    | dep_name  | max_salary |
    +-----------+------------+
    | 咨询部    |      10.00 |
    | 教学部    |      10.80 |
    | 教职部    |      11.50 |
    | 打杂部    |     100.00 |
    +-----------+------------+
    
    3.修改t1表中的最大工资+1,条件是他的部门必须存在于emp表中的dep_anme中(修改的条件是一个子查询)
    update t1 set max_salary=max_salary+1 where dep_name in (select distinct dep from  
    emp);
    mysql> select * from t1;
    +-----------+------------+
    | dep_name  | max_salary |
    +-----------+------------+
    | 咨询部    |      11.00 |
    | 教学部    |      11.80 |
    | 教职部    |      12.50 |
    | 打杂部    |     100.00 |
    +-----------+------------+
    
    4.错误:update更新的表 与 子查询select的表 相同
    update t1 set max_salary=max_salary+1 where dep_name in (select distinct dep_name     
    from    t1);
    
    
5.删除操作:删除t1表中部门在emp中也有的部门
delete from t1 where dep_name in (select distinct dep from emp);
# 错误: delete删除的表 与 子查询select的表 相同
delete from t1 where dep_name in (select distinct dep_name from t1);
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Easter79 Easter79
3年前
sql注入
反引号是个比较特别的字符,下面记录下怎么利用0x00SQL注入反引号可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景,下面具体说下1)表名payload:select\from\users\whereuser\_id1limit0,1;!(https://o
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Wesley13 Wesley13
3年前
MySQL总结(十一)子查询
!(https://oscimg.oschina.net/oscnet/upa344f41e81d3568e3310b5da00c57ced8ea.png)子查询1\.什么是子查询需求:查询开发部中有哪些员工selectfromemp;通
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
mysql5.6 分页查询优化
mysql5.6分页查询优化场景:表结构:主键(非自增)contentCode(varchar),过滤条件列为updateTime(timeStamp),已经为timestamp建立索引。搜索sql为:SELECTFROMmy_hello_tableWHEREupdat
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究