04 数据库入门学习-单表查询、多表查询、子查询

1.复制表

#创建了一张测试表
mysql>create table test (id int primary key auto_increment,name char(10));

#显示原表结构
mysql> desc test;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(10) | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+

#显示原表数据
mysql> select *from test;
+----+------+
| id | name |
+----+------+
|  1 | a    |
+----+------+

#复制表
mysql> create table copy select *from test;

#显示复制表的结构
mysql> desc copy;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(11)  | NO   |     | 0       |       |
| name  | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+

#显示复制表的数据
mysql> select *from copy;
+----+------+
| id | name |
+----+------+
|  1 | a    |
+----+------+

总结:复制表,只是拷贝结构与数据,但是索引、 描述不能拷贝(自增)

2.单表查询

2.1完整的查询语句 

#[]可选    {}必选   |或

select [distinct] {* | 字段名 | 聚合函数 | 表达式} from 表名
[where 条件
group by 字段名
having 条件
order by 字段名
limit 显示的条数]

#注意:关键字的顺序必须与上述语法一致

2.2执行顺序

1.from,先找到文件/表

2.where,拿着where的约束条件,与文件/表中的记录依次比较,正确的数据取出来

3.group,对取出来的数据进行分组

4.having,对分组的数据进行过滤

5.distinct,去重

6.order by,对筛选后的数据排序

7.limit,限制结果的显示条数

2.3简单查询

#准备表
create table stu(id int primary key auto_increment,name char(10),math float,english float); insert into stu values(null,"赵云",90,30); insert into stu values(null,"小乔",90,60); insert into stu values(null,"小乔",90,60); insert into stu values(null,"大乔",10,70); insert into stu values(null,"李清照",100,100); insert into stu values(null,"铁拐李",20,55); insert into stu values(null,"小李子",20,55);

mysql> select *from stu;
+----+-----------+------+---------+
| id | name      | math | english |
+----+-----------+------+---------+
|  1 | 赵云      |   90 |      30 |
|  2 | 小乔      |   90 |      60 |
|  3 | 小乔      |   90 |      60 |
|  4 | 大乔      |   10 |      70 |
|  5 | 李清照    |  100 |     100 |
|  6 | 铁拐李    |   20 |      55 |
|  7 | 小李子    |   20 |      55 |
+----+-----------+------+---------+

#避免重复
mysql> select distinct name from stu;
+-----------+
| name      |
+-----------+
| 赵云      |
| 小乔      |
| 大乔      |
| 李清照    |
| 铁拐李    |
| 小李子    |
+-----------+

#四则运算
mysql> select name,math+10 as math from stu;
+-----------+------+
| name      | math |
+-----------+------+
| 赵云      |  100 |
| 小乔      |  100 |
| 小乔      |  100 |
| 大乔      |   20 |
| 李清照    |  110 |
| 铁拐李    |   30 |
| 小李子    |   30 |
+-----------+------+

#显示格式
mysql>  select
    ->  concat("name:",name),
    ->  concat("english:",english),
    ->   concat("math:",math)
    ->   from stu;
+----------------------+----------------------------+----------------------+
| concat("name:",name) | concat("english:",english) | concat("math:",math) |
+----------------------+----------------------------+----------------------+
| name:赵云            | english:30                 | math:90              |
| name:小乔            | english:60                 | math:90              |
| name:小乔            | english:60                 | math:90              |
| name:大乔            | english:70                 | math:10              |
| name:李清照          | english:100                | math:100             |
| name:铁拐李          | english:55                 | math:20              |
| name:小李子          | english:55                 | math:20              |
+----------------------+----------------------------+----------------------+

2.4 where

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

+----+-----------+------+---------+
| id | name      | math | english |
+----+-----------+------+---------+
|  1 | 赵云      |   90 |      30 |
|  2 | 小乔      |   90 |      60 |
|  3 | 小乔      |   90 |      60 |
|  4 | 大乔      |   10 |      70 |
|  5 | 李清照    |  100 |     100 |
|  6 | 铁拐李    |   20 |      55 |
|  7 | 小李子    |   20 |      55 |
+----+-----------+------+---------+

#1. 比较运算符:> < >= <= <> !=
mysql> select *from stu where math>70;
+----+-----------+------+---------+
| id | name      | math | english |
+----+-----------+------+---------+
|  1 | 赵云      |   90 |      30 |
|  2 | 小乔      |   90 |      60 |
|  3 | 小乔      |   90 |      60 |
|  5 | 李清照    |  100 |     100 |
+----+-----------+------+---------+

#2. between and
mysql> select *from stu where math between 80 and 100 ;
+----+-----------+------+---------+
| id | name      | math | english |
+----+-----------+------+---------+
|  1 | 赵云      |   90 |      30 |
|  2 | 小乔      |   90 |      60 |
|  3 | 小乔      |   90 |      60 |
|  5 | 李清照    |  100 |     100 |
+----+-----------+------+---------+

#3. in
mysql> select *from stu where math in (80,90,100) ;
+----+-----------+------+---------+
| id | name      | math | english |
+----+-----------+------+---------+
|  1 | 赵云      |   90 |      30 |
|  2 | 小乔      |   90 |      60 |
|  3 | 小乔      |   90 |      60 |
|  5 | 李清照    |  100 |     100 |
+----+-----------+------+---------+

#4. like %或_
mysql> select *from stu where name like ‘小_‘ ;
+----+--------+------+---------+
| id | name   | math | english |
+----+--------+------+---------+
|  2 | 小乔   |   90 |      60 |
|  3 | 小乔   |   90 |      60 |
+----+--------+------+---------+

mysql> select *from stu where name like ‘李%‘ ;
+----+-----------+------+---------+
| id | name      | math | english |
+----+-----------+------+---------+
|  5 | 李清照    |  100 |     100 |
+----+-----------+------+---------+

#5. and or not
mysql> select *from stu where math=90 and english=60;
+----+--------+------+---------+
| id | name   | math | english |
+----+--------+------+---------+
|  2 | 小乔   |   90 |      60 |
|  3 | 小乔   |   90 |      60 |
+----+--------+------+---------+

2.5 group by

用于给数据分组

  1.在生活中是为了方便管理
  2.在数据库中是为了 方便统计

可以按照任意字段分组,但是分组完毕后,只能查看分组的字段,如果想查看组内信息,需要借助于聚合函数

聚合函数:
  将一堆数据经过计算,得到一个数据
  sum() 求和
  avg() 求平均数
  max()/min() 求最大值 / 最小值
  count() 个数

#由于没有设置ONLY_FULL_GROUP_BY,于是也可以有结果,默认都是组内的第一条记录,但其实这是没有意义的

mysql> set global sql_mode=‘ONLY_FULL_GROUP_BY‘;
Query OK, 0 rows affected (0.00 sec)

mysql> quit #设置成功后,一定要退出,然后重新登录方可生效

#准备数据
create table emp (id int,name char(10),sex char,dept char(10),job char(10),salary double);
insert into emp values (1,"刘备","男","市场","总监",5800),
(2,"张飞","男","市场","员工",3000),
(3,"关羽","男","市场","员工",4000),
(4,"孙权","男","行政","总监",6000),
(5,"周瑜","男","行政","员工",5000),
(6,"小乔","女","行政","员工",4000),
(7,"曹操","男","财务","总监",10000),
(8,"司马懿","男","财务","员工",6000);

#查询每个部门有几个人
mysql> select dept,count(*)as 人数  from emp group by dept;
+--------+--------+
| dept   | 人数   |
+--------+--------+
| 市场   |      3 |
| 行政   |      3 |
| 财务   |      2 |
+--------+--------+

#计算每个部门的平均工资
mysql> select dept,avg(salary)as 平均工资  from emp group by dept;
+--------+-------------------+
| dept   | 平均工资          |
+--------+-------------------+
| 市场   | 4266.666666666667 |
| 行政   |              5000 |
| 财务   |              8000 |
+--------+-------------------+

2.6 having

用于对分组后的数据进行过滤
1. having不会单独出现 都是和group by 一起出现

2. where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。

3. having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数

#准备数据
mysql> create table emp (id int,name char(10),sex char,dept char(10),job char(10),salary double);

mysql> insert into emp values (1,"刘备","男","市场","总监",5800),
    -> (2,"张飞","男","市场","员工",3000),
    -> (3,"关羽","男","市场","员工",4000),
    -> (4,"孙权","男","行政","总监",6000),
    -> (5,"周瑜","男","行政","员工",5000),
    -> (6,"小乔","女","行政","员工",4000),
    -> (7,"曹操","男","财务","总监",10000),
    -> (8,"司马懿","男","财务","员工",6000);

mysql> select *from emp;
+------+-----------+------+--------+--------+--------+
| id   | name      | sex  | dept   | job    | salary |
+------+-----------+------+--------+--------+--------+
|    1 | 刘备      | 男   | 市场   | 总监   |   5800 |
|    2 | 张飞      | 男   | 市场   | 员工   |   3000 |
|    3 | 关羽      | 男   | 市场   | 员工   |   4000 |
|    4 | 孙权      | 男   | 行政   | 总监   |   6000 |
|    5 | 周瑜      | 男   | 行政   | 员工   |   5000 |
|    6 | 小乔      | 女   | 行政   | 员工   |   4000 |
|    7 | 曹操      | 男   | 财务   | 总监   |  10000 |
|    8 | 司马懿    | 男   | 财务   | 员工   |   6000 |
+------+-----------+------+--------+--------+--------+

#查询平均工资大于5000的部门
mysql> select dept,avg(salary)as 平均工资  from emp group by dept having avg(salary)>5000;
+--------+--------------+
| dept   | 平均工资     |
+--------+--------------+
| 财务   |         8000 |
+--------+--------------+

#查询每个职位有多少人
mysql> select job,count(*)as 人数  from emp group by job;
+--------+--------+
| job    | 人数   |
+--------+--------+
| 员工   |      5 |
| 总监   |      3 |
+--------+--------+

2.7 order by

用于对记录进行 排序

desc为降序
asc为升序

#准备数据
mysql> create table emp (id int,name char(10),sex char,dept char(10),job char(10),salary double);

mysql> insert into emp values (1,"刘备","男","市场","总监",5800),
    -> (2,"张飞","男","市场","员工",3000),
    -> (3,"关羽","男","市场","员工",4000),
    -> (4,"孙权","男","行政","总监",6000),
    -> (5,"周瑜","男","行政","员工",5000),
    -> (6,"小乔","女","行政","员工",4000),
    -> (7,"曹操","男","财务","总监",10000),
    -> (8,"司马懿","男","财务","员工",6000);

mysql> select *from emp;
+------+-----------+------+--------+--------+--------+
| id   | name      | sex  | dept   | job    | salary |
+------+-----------+------+--------+--------+--------+
|    1 | 刘备      | 男   | 市场   | 总监   |   5800 |
|    2 | 张飞      | 男   | 市场   | 员工   |   3000 |
|    3 | 关羽      | 男   | 市场   | 员工   |   4000 |
|    4 | 孙权      | 男   | 行政   | 总监   |   6000 |
|    5 | 周瑜      | 男   | 行政   | 员工   |   5000 |
|    6 | 小乔      | 女   | 行政   | 员工   |   4000 |
|    7 | 曹操      | 男   | 财务   | 总监   |  10000 |
|    8 | 司马懿    | 男   | 财务   | 员工   |   6000 |

#按单列排序
#默认是ASC升序
mysql> SELECT * FROM emp ORDER BY salary;
+------+-----------+------+--------+--------+--------+
| id   | name      | sex  | dept   | job    | salary |
+------+-----------+------+--------+--------+--------+
|    2 | 张飞      | 男   | 市场   | 员工   |   3000 |
|    3 | 关羽      | 男   | 市场   | 员工   |   4000 |
|    6 | 小乔      | 女   | 行政   | 员工   |   4000 |
|    5 | 周瑜      | 男   | 行政   | 员工   |   5000 |
|    1 | 刘备      | 男   | 市场   | 总监   |   5800 |
|    4 | 孙权      | 男   | 行政   | 总监   |   6000 |
|    8 | 司马懿    | 男   | 财务   | 员工   |   6000 |
|    7 | 曹操      | 男   | 财务   | 总监   |  10000 |
+------+-----------+------+--------+--------+--------+

#升序
mysql> SELECT * FROM emp ORDER BY salary ASC;
+------+-----------+------+--------+--------+--------+
| id   | name      | sex  | dept   | job    | salary |
+------+-----------+------+--------+--------+--------+
|    2 | 张飞      | 男   | 市场   | 员工   |   3000 |
|    3 | 关羽      | 男   | 市场   | 员工   |   4000 |
|    6 | 小乔      | 女   | 行政   | 员工   |   4000 |
|    5 | 周瑜      | 男   | 行政   | 员工   |   5000 |
|    1 | 刘备      | 男   | 市场   | 总监   |   5800 |
|    4 | 孙权      | 男   | 行政   | 总监   |   6000 |
|    8 | 司马懿    | 男   | 财务   | 员工   |   6000 |
|    7 | 曹操      | 男   | 财务   | 总监   |  10000 |
+------+-----------+------+--------+--------+--------+

#降序
mysql> SELECT * FROM emp ORDER BY salary DESC;
+------+-----------+------+--------+--------+--------+
| id   | name      | sex  | dept   | job    | salary |
+------+-----------+------+--------+--------+--------+
|    7 | 曹操      | 男   | 财务   | 总监   |  10000 |
|    4 | 孙权      | 男   | 行政   | 总监   |   6000 |
|    8 | 司马懿    | 男   | 财务   | 员工   |   6000 |
|    1 | 刘备      | 男   | 市场   | 总监   |   5800 |
|    5 | 周瑜      | 男   | 行政   | 员工   |   5000 |
|    3 | 关羽      | 男   | 市场   | 员工   |   4000 |
|    6 | 小乔      | 女   | 行政   | 员工   |   4000 |
|    2 | 张飞      | 男   | 市场   | 员工   |   3000 |
+------+-----------+------+--------+--------+--------+

按多列排序:

#先按照职位排序,如果职位相同,则按照薪资排序

mysql> SELECT * from emp ORDER BY job, salary DESC;
+------+-----------+------+--------+--------+--------+
| id   | name      | sex  | dept   | job    | salary |
+------+-----------+------+--------+--------+--------+
|    8 | 司马懿    | 男   | 财务   | 员工   |   6000 |
|    5 | 周瑜      | 男   | 行政   | 员工   |   5000 |
|    3 | 关羽      | 男   | 市场   | 员工   |   4000 |
|    6 | 小乔      | 女   | 行政   | 员工   |   4000 |
|    2 | 张飞      | 男   | 市场   | 员工   |   3000 |
|    7 | 曹操      | 男   | 财务   | 总监   |  10000 |
|    4 | 孙权      | 男   | 行政   | 总监   |   6000 |
|    1 | 刘备      | 男   | 市场   | 总监   |   5800 |
+------+-----------+------+--------+--------+--------+

2.8 limit

  用于限制显示的条数
  limit [start,]count

#准备数据
mysql> create table emp (id int,name char(10),sex char,dept char(10),job char(10),salary double);

mysql> insert into emp values (1,"刘备","男","市场","总监",5800),
    -> (2,"张飞","男","市场","员工",3000),
    -> (3,"关羽","男","市场","员工",4000),
    -> (4,"孙权","男","行政","总监",6000),
    -> (5,"周瑜","男","行政","员工",5000),
    -> (6,"小乔","女","行政","员工",4000),
    -> (7,"曹操","男","财务","总监",10000),
    -> (8,"司马懿","男","财务","员工",6000);

mysql> select *from emp;
+------+-----------+------+--------+--------+--------+
| id   | name      | sex  | dept   | job    | salary |
+------+-----------+------+--------+--------+--------+
|    1 | 刘备      | 男   | 市场   | 总监   |   5800 |
|    2 | 张飞      | 男   | 市场   | 员工   |   3000 |
|    3 | 关羽      | 男   | 市场   | 员工   |   4000 |
|    4 | 孙权      | 男   | 行政   | 总监   |   6000 |
|    5 | 周瑜      | 男   | 行政   | 员工   |   5000 |
|    6 | 小乔      | 女   | 行政   | 员工   |   4000 |
|    7 | 曹操      | 男   | 财务   | 总监   |  10000 |
|    8 | 司马懿    | 男   | 财务   | 员工   |   6000 |
+------+-----------+------+--------+--------+--------+

# 看看表里前三条数据
mysql> select *from emp limit 3;
+------+--------+------+--------+--------+--------+
| id   | name   | sex  | dept   | job    | salary |
+------+--------+------+--------+--------+--------+
|    1 | 刘备   | 男   | 市场   | 总监   |   5800 |
|    2 | 张飞   | 男   | 市场   | 员工   |   3000 |
|    3 | 关羽   | 男   | 市场   | 员工   |   4000 |
+------+--------+------+--------+--------+--------+

# 看看表里的3-5条
mysql> select *from emp limit 2,3;
+------+--------+------+--------+--------+--------+
| id   | name   | sex  | dept   | job    | salary |
+------+--------+------+--------+--------+--------+
|    3 | 关羽   | 男   | 市场   | 员工   |   4000 |
|    4 | 孙权   | 男   | 行政   | 总监   |   6000 |
|    5 | 周瑜   | 男   | 行政   | 员工   |   5000 |
+------+--------+------+--------+--------+--------+

# 查看工资最高的那个人的信息
mysql> select *from emp order by salary desc  limit 1;
+------+--------+------+--------+--------+--------+
| id   | name   | sex  | dept   | job    | salary |
+------+--------+------+--------+--------+--------+
|    7 | 曹操   | 男   | 财务   | 总监   |  10000 |
+------+--------+------+--------+--------+--------+

3.多表查询

在多个表中查询需要的数据
例如:有班级表和学生表
  给你一个班级名称, 请查询所有的学员数据
  先查班级表 得到一个班级的id, 再根据id去学院表查询对应的学员

#准备数据:
create table emp (id int,name char(10),sex char,dept_id int);
insert emp values(1,"大黄","m",1);
insert emp values(2,"老王","m",2);
insert emp values(3,"老李","w",30);
mysql> select *from emp;
+------+--------+------+---------+
| id   | name   | sex  | dept_id |
+------+--------+------+---------+
|    1 | 大黄   | m    |       1 |
|    2 | 老王   | m    |       2 |
|    3 | 老李   | w    |      30 |
+------+--------+------+---------+

create table dept (id int,name char(10));
insert dept values(1,"市场");
insert dept values(2,"财务");
mysql> select *from dept;
+------+--------+
| id   | name   |
+------+--------+
|    1 | 市场   |
|    2 | 财务   |
|    3 | 行政   |
+------+--------+
insert dept values(3,"行政");

多表查询的方式

1.笛卡尔积查询

#什么是笛卡尔积,用坐标中的一条记录,去链接另一张表的所有记录
#就像是把两张表的数据做了一个乘法
#这将导致产生大量的无用重复数据
#我们要的效果是:员工表中的部门id与部门表中的id相同,就拼接在一起
#用 where 筛选出正确的数据
mysql> select *from emp,dept where emp.dept_id=dept.id;
+------+--------+------+---------+------+--------+
| id   | name   | sex  | dept_id | id   | name   |
+------+--------+------+---------+------+--------+
|    1 | 大黄   | m    |       1 |    1 | 市场   |
|    2 | 老王   | m    |       2 |    2 | 财务   |
+------+--------+------+---------+------+--------+

2.内连接查询

#inner  join...on...
mysql> select *from emp inner join dept on emp.dept_id=dept.id;
+------+--------+------+---------+------+--------+
| id   | name   | sex  | dept_id | id   | name   |
+------+--------+------+---------+------+--------+
|    1 | 大黄   | m    |       1 |    1 | 市场   |
|    2 | 老王   | m    |       2 |    2 | 财务   |
+------+--------+------+---------+------+--------+
#与from...where...一样,只不过inner  join...on...是专门用于多表连接的

3.左外连接

left join
#左边员工表中的数据完全显示,右边表中的数据匹配上才显示,没有则NULL
mysql> select *from emp left  join dept on emp.dept_id=dept.id;
+------+--------+------+---------+------+--------+
| id   | name   | sex  | dept_id | id   | name   |
+------+--------+------+---------+------+--------+
|    1 | 大黄   | m    |       1 |    1 | 市场   |
|    2 | 老王   | m    |       2 |    2 | 财务   |
|    3 | 老李   | w    |      30 | NULL | NULL   |
+------+--------+------+---------+------+--------+

4.右外连接

right join
#右边表中的数据完全显示,左边表中的数据匹配上才显示
mysql> select *from emp right  join dept on emp.dept_id=dept.id;
+------+--------+------+---------+------+--------+
| id   | name   | sex  | dept_id | id   | name   |
+------+--------+------+---------+------+--------+
|    1 | 大黄   | m    |       1 |    1 | 市场   |
|    2 | 老王   | m    |       2 |    2 | 财务   |
| NULL | NULL   | NULL |    NULL |    3 | 行政   |
+------+--------+------+---------+------+--------+

5. 全外链接

#全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果
#mysql不支持 full join,但是可以用union间接实现

union:表示合并查询,意思是把多个查询结果合并在一起显示,要求是被合并的表结构必须相同,默认去除重复

union all:合并但是不去除重复

sql> select *from emp right join dept  on emp.dept_id = dept.id
    ->union
    ->select *from emp left join dept  on emp.dept_id = dept.id;
+------+--------+------+---------+------+--------+
| id   | name   | sex  | dept_id | id   | name   |
+------+--------+------+---------+------+--------+
|    1 | 大黄   | m    |       1 |    1 | 市场   |
|    2 | 老王   | m    |       2 |    2 | 财务   |
| NULL | NULL   | NULL |    NULL |    3 | 行政   |
|    3 | 老李   | w    |      30 | NULL | NULL   |
+------+--------+------+---------+------+--------+

6.三表查询

#准备数据
#老师表
create table tec(id int,name char(10));
insert into tec value(1,"egon");
insert into tec value(2,"yyh");
mysql> select *from tec;
+------+------+
| id   | name |
+------+------+
|    1 | egon |
|    2 | yyh  |
+------+------+

#学生表
create table stu(id int,name char(10));
insert into stu value(1,"大傻");
insert into stu value(2,"中傻");
insert into stu value(3,"小傻");
mysql> select *from stu;
+------+--------+
| id   | name   |
+------+--------+
|    1 | 大傻   |
|    2 | 中傻   |
|    3 | 小傻   |

#关联表
create table s_t(s_id int,t_id int);
insert into s_t value(1,2);
insert into s_t value(2,2);
insert into s_t value(3,1);
mysql> select *from s_t;
+------+------+
| s_id | t_id |
+------+------+
|    1 |    2 |
|    2 |    2 |
|    3 |    1 |
+------+------+

#需求  找出 yyh 这个老师 教过的学生信息
#思路:
#    第一步,到关系表中去查询,哪些老师教过哪些学生(学生的id),形成了一个临时表
mysql> select *from tec inner join s_t on tec.id=s_t.t_id;
+------+------+------+------+
| id   | name | s_id | t_id |
+------+------+------+------+
|    2 | yyh  |    1 |    2 |
|    2 | yyh  |    2 |    2 |
|    1 | egon |    3 |    1 |
+------+------+------+------+

#    第二步, 将上一步得到临时表与学生表进行连接
mysql> select *from tec inner join s_t on tec.id=s_t.t_id
    -> inner join stu on s_id=stu.id;
+------+------+------+------+------+--------+
| id   | name | s_id | t_id | id   | name   |
+------+------+------+------+------+--------+
|    2 | yyh  |    1 |    2 |    1 | 大傻   |
|    2 | yyh  |    2 |    2 |    2 | 中傻   |
|    1 | egon |    3 |    1 |    3 | 小傻   |
+------+------+------+------+------+--------+

#    第三步,加上额外的筛选条件,老师的name是yyh
mysql> select tec.name as 老师名字  ,stu.name as 学生名字  from tec inner join s_t on tec.id=s_t.t_id
    -> inner join stu on s_id=stu.id
    -> where tec.name=‘yyh‘;
+--------------+--------------+
| 老师名字     | 学生名字     |
+--------------+--------------+
| yyh          | 大傻         |
| yyh          | 中傻         |
+--------------+--------------+

4.子查询

子查询:将上一次查询的结果作为本次查询的原始数据(或是查询条件)

#准备数据
create table emp (id int,name char(10),sex char,dept char(10),job char(10),salary double);
insert into emp values (1,"刘备","男","市场","总监",5800),
(2,"张飞","男","市场","员工",3000),
(3,"关羽","男","市场","员工",4000),
(4,"孙权","男","行政","总监",6000),
(5,"周瑜","男","行政","员工",5000),
(6,"小乔","女","行政","员工",4000),
(7,"曹操","男","财务","总监",10000),
(8,"司马懿","男","财务","员工",6000);

#需求:查询出工资最高的人的信息
#先查询出最高工资是多少
#拿着最高工资去表中看,谁的工资和最高工资匹配

mysql> select *from emp where salary=(select max(salary) from emp);
+------+--------+------+--------+--------+--------+
| id   | name   | sex  | dept   | job    | salary |
+------+--------+------+--------+--------+--------+
|    7 | 曹操   | 男   | 财务   | 总监   |  10000 |
+------+--------+------+--------+--------+--------+
#in 关键字子查询
#查询平均年龄大于25的部门名称
#1.求每个部门的平均年龄
select avg(age) from emp group by dept_id;
#2.筛选结果
select dept_id,avg(age) as a from emp group by dept_id having a > 25;
#3.最后
select name from dept where id in (select dept_id from emp group by dept_id having avg(age) > 25);

#子查询方式:
#平均年龄大于25的部门有哪些?
#先要求出每个部门的平年龄!每个表示什么? 分组
select name from dept where id in  (select dept_id from emp group by dept_id having avg(age) > 25);

#多表查询方式:
#先把数据拼接到一起 在加以筛选
select dept.name from emp inner join dept
on emp.dept_id = dept.id
group by dept.name
having avg(age) >25;

#exists关键字子查询
#exists  后跟子查询  子查询有结果是为True 没有结果时为False
#为true时外层执行 为false外层不执行
select *from emp where exists (select *from emp where salary > 1000);
select (exists (select *from emp where salary > 10000));

原文地址:https://www.cnblogs.com/ouyang99-/p/10354769.html

时间: 2024-10-19 00:28:20

04 数据库入门学习-单表查询、多表查询、子查询的相关文章

sql的基础语句-单行函数,dual,数字函数,日期函数,表连接,集合运算,分组报表,单行子查询,多行子查询

3. 单行函数 3.1 转换函数 select ascii('A'),chr(65) from dual; select to_char(1243123),1231451 from dual;靠左边的就是字符串,靠右边的就是数字 select to_char(123512a121) from dual;   --错误的写法,没有引号表示数字,但是数字里面包含了字母,不合法的输入值 select to_number('123141211') from dual; select to_number(

[Z]T-SQL查询进阶--深入理解子查询

原文链接: http://www.cnblogs.com/CareySon/archive/2011/07/18/2109406.html 引言 SQL有着非常强大且灵活的查询方式,而多表连接操作往往也可以用子查询进行替代,本篇文章将会讲述子查询的方方面面. 简介 子查询本质上是嵌套进其他SELECT,UPDATE,INSERT,DELETE语句的一个被限制的SELECT语句,在子查询中,只有下面几个子句可以使用 SELECT子句(必须) FROM子句(必选) WHERE子句(可选) GROUP

1.子查询知识体系,单行子查询,多行子查询

 1查询工资比scott高的员工信息 A 第一步:查询出scott这个员工的工资 select sal from emp where ename = 'SCOTT'; B 第二步:查询出工资比scott高的员工信息 select * fromemp where sal >3000; 总结: 子查询的本质:多个select语句的嵌套 2:子查询的知识体系搭建 A 合理的书写风格 B 子查询外面()不要忘记 C 子查询和主查询可以查询的是同一张表,也可以不是同一张表 只要子查询返回的结果,主查询

Entity Framework查询生成大量的子查询,如何避免?求救

最近使用Entity Framework做一个中型的项目,一张表含有千万条数据,并没有使用很复杂的查询,只是程序上使用了DTO进行帅选数据,且使用了分页,效果很不理想.经过跟踪sql,我发现很多简单的查询,都存在子查询,而子查询往往会影响到查询性能,在这里,我想问问大虾,除了自己写SQL语句,有没有更好的解决办法在Entity Framework基础上处理这个问题? 如图所示: Entity Framework查询代码 private async Task<QuotationDto[]> Ge

数据库(学习整理)----7--Oracle多表查询,三种join连接

聚合函数:(都会忽略null数据) 常用的有5种:将字段中所有的数据聚合在一条中 1.sum(字段名) :求总和 2.avg(字段名) :求平均值 3.max(字段名) :求最大值 4.min(字段名) :求最小值 5.count(字段名.*) :统计行数 ----2.按部门编号,查询平均薪水 ,并且平均薪水<1300的不显示,结果按降序排序 select empno,avg(sal) as avgsal from scott.emp group by empno having avg(sal)

salesforce 零基础开发入门学习(四)多表关联下的SOQL以及表字段Data type详解

建立好的数据表在数据库中查看有很多方式,本人目前采用以下两种方式查看数据表. 1.采用schema Builder查看表结构以及多表之间的关联关系,可以登录后点击setup在左侧搜索框输入schema Builder 或者build-->schema Builder进入: 2.采用force.com Explorer通过自己写查询语句来查询数据. 此链接为force.com Explorer的下载链接:  http://force-com-explorer-beta.software.infor

MySQL基础入门学习【10】多表删除

DELETE tbl_name [.*] [, tbl_name[.*]]... FROM table_references [WHERE where_condition] 现在想把重复的记录删除掉,保留id号比较小的记录. 一张表模拟多表删除来实现: (1) 查找重复记录 (2) 参照这张表来删除上面那个表中的数据 [涉及 子查询.连接.多表更新.多表删除 : 多表操作时实现了自身的连接:通过自身的连接删除重复的记录] 原文地址:https://www.cnblogs.com/jade-91/

03 数据库入门学习-完整性约束、关联关系

一.完整性约束 1.什么是约束 为了保证数据的合法性与完整性,对字段进行了除了数据类型以外添加额外的约束. 2.not null 2.1意义 not null是非空约束,数据不能为空 2.2语法 create table student (id int,name char(10) not null);#名字不能为空 3.default 3.1意义 default  默认值约束,可以指定字段的默认值 3.2语法 create table user (id int,name char(10) not

数据库 基础学习8— 横标与纵表转换

一.纵表转横表: 1 create table Student--学生表 2 ( 3 Sno char(3) primary key not null,--学号(主键) 4 Sname char(8) not null,--学生姓名 5 Ssex char(2) not null,--学生性别 6 Sbirthday datetime,--学生出生年月 7 Class char(5)--学生所在班级 8 ) 9 go 10 create table Teacher--教师表 11 ( 12 Tn