单表多表操作 联表查询

目录

  • 一、单表操作

    • 1. 分组——> group by
    • 2. 排序——> order by
    • 3. 分页——> limit
    • 4. 总结(很重要)
  • 二、多表操作
    • 1. 外键
    • 2. 一对多(很常见类型)
    • 3. 多对多(常见类型)
    • 4. 一对一(不常见类型)
  • 三、多表联查
    • 1. 左连接——>left join...on
    • 2. 右连接——>right join...on
    • 3. 内连接——>inner join...on

一、单表操作

1. 分组——> group by

  • 分组指的是:将所有表记录按照某个相同字段进行归类
  • 用法:
    • select 聚合函数,选取的字段 from 表名 group by 选择分组的字段 having 条件
    • 聚合函数:count/sum/max/min/avg
    • having:表示对group by之后的数据,进行再一次的筛选
    • 注意:group by必须和集合函数一起使用。
    • where 条件语句和groupby分组语句的先后顺序:
      where > group by > having(*********)
  • 实例:
    mysql> select depart_id,avg(age) from employee group by depart_id ;
                  +-----------+----------+
                  | depart_id | avg(age) |
                  +-----------+----------+
                  |         1 |  45.2500 |
                  |         2 |  30.0000 |
                  |         3 |  20.0000 |
                  +-----------+----------+
                  3 rows in set (0.00 sec)
    
                  mysql> select depart_id,avg(age) from employee group by depart_id having avg(age) > 35;
                  +-----------+----------+
                  | depart_id | avg(age) |
                  +-----------+----------+
                  |         1 |  45.2500 |
                  +-----------+----------+
                  1 row in set (0.00 sec)

2. 排序——> order by

  • order by对查询的结果进行排序
  • 用法:
    • order by 字段名 asc/desc ,其中asc默认的表示升序排序,desc表示降序排序
    • 如果对多个字段进行排序,如 order by age desc , id asc,则先对age进行降序排序,如果排完序记录中有相同的age时,再把有相同的这些行按id升序排序。

3. 分页——> limit

  • 用法:

    • limit 参数1 , 参数2 。参数1表示行索引,从该行开始,表记录第第一行数据的索引是0,往下递增,参数2表示取多少行。

4. 总结(很重要)

  • 以上高级用法的使用顺序是:

    • select * from 表名 where 条件 group by 条件 having 条件 order by 条件 limit 条件;
    • where > group by > having > order by > limit

二、多表操作

1. 外键

  • 使用外键的原因:

    • 减少占用的空间
    • 只需要修改一次原表中的数据 ,其余有对应外键的表中的数据就会相应的修改。
  • 使用方法:

    constraint 外键名 foreign key (被约束的字段) references 约束的表(约束的字段)

2. 一对多(很常见类型)

  • 实例:

    create table department(
                      id int auto_increment primary key,
                      name varchar(32) not null default ''
                  )charset utf8;
    
                  insert into department (name) values ('研发部');
                  insert into department (name) values ('运维部');
                  insert into department (name) values ('前台部');
                  insert into department (name) values ('小卖部');
    
                  create table userinfo (
                      id int auto_increment primary key,
                      name varchar(32) not null default '',
                      depart_id int not null default 1,
    
                      constraint fk_user_depart foreign key (depart_id) references department(id),
    
                  )charset utf8;
    
                  insert into userinfo (name, depart_id) values ('zekai', 1);
                  insert into userinfo (name, depart_id) values ('xxx', 2);
                  insert into userinfo (name, depart_id) values ('zekai1', 3);
                  insert into userinfo (name, depart_id) values ('zekai2', 4);
                  insert into userinfo (name, depart_id) values ('zekai3', 1);
                  insert into userinfo (name, depart_id) values ('zekai4', 2);
                  insert into userinfo (name, depart_id) values ('zekai4', 5);

3. 多对多(常见类型)

  • 实例:

    create table boy (
                      id int auto_increment primary key,
                      bname varchar(32) not null default ''
                  )charset utf8;
    
                  insert into boy (bname) values ('zhangsan'),('lisi'),('zhaoliu');
    
                  create table girl (
                      id int auto_increment primary key,
                      gname varchar(32) not null default ''
                  )charset utf8;
                  insert into girl (gname) values ('cuihua'),('gangdan'),('jianguo');
    
                  create table boy2girl (
                      id int auto_increment primary key,
                      bid int not null default 1,
                      gid int not null default 1,
    
                      constraint fk_boy2girl_boy foreign key (bid) references boy(id),
                      constraint fk_boy2girl_girl foreign key (gid) references girl(id)
                  )charset utf8;
    
                  insert into boy2girl (bid, gid) values (1,1),(1,2),(2,3),(3,3),(2,2);
    
                  select * from boy left join  boy2girl on boy.id = boy2girl.bid left join girl on girl.id=boy2girl.gid;
    
                  mysql> select * from boy left join  boy2girl on boy.id = boy2girl.bid left join girl on girl.id=boy2girl.gid;
                  +----+----------+------+------+------+------+---------+
                  | id | bname    | id   | bid  | gid  | id   | gname   |
                  +----+----------+------+------+------+------+---------+
                  |  1 | zhangsan |    1 |    1 |    1 |    1 | cuihua  |
                  |  1 | zhangsan |    2 |    1 |    2 |    2 | gangdan |
                  |  2 | lisi     |    5 |    2 |    2 |    2 | gangdan |
                  |  2 | lisi     |    3 |    2 |    3 |    3 | jianguo |
                  |  3 | zhaoliu  |    4 |    3 |    3 |    3 | jianguo |
                  +----+----------+------+------+------+------+---------+
                  5 rows in set (0.00 sec)
    
                  mysql> select bname, gname from boy left join  boy2girl on boy.id = boy2girl.bid left join girl on girl.id=boy2girl.gid;
                  +----------+---------+
                  | bname    | gname   |
                  +----------+---------+
                  | zhangsan | cuihua  |
                  | zhangsan | gangdan |
                  | lisi     | gangdan |
                  | lisi     | jianguo |
                  | zhaoliu  | jianguo |
                  +----------+---------+
                  5 rows in set (0.00 sec)
    
                  mysql> select bname, gname from boy left join  boy2girl on boy.id = boy2girl.bid left join girl on girl.id=boy2girl.gid where bname='zhangsan';
                  +----------+---------+
                  | bname    | gname   |
                  +----------+---------+
                  | zhangsan | cuihua  |
                  | zhangsan | gangdan |
                  +----------+---------+
                  2 rows in set (0.02 sec)

4. 一对一(不常见类型)

  • 实例:

    user :
                      id   name  age
                      1    zekai  18
                      2    zhangsan 23
                      3    xxxx   19   
    
                  由于salary是比较敏感的字段,因此我们需要将此字段单独拆出来, 变成一张独立的表
    
                  private:
    
                      id  salary   uid  (外键 + unique)
                      1    5000     1
                      2    6000     2
                      3    3000     3
    
                  create table user (
                      id int auto_increment primary key,
                      name varchar(32) not null default ''
                  )charset=utf8;
    
                  insert into user (name) values ('zhangsan'),('zekai'),('kkk');
    
                  create table priv(
                      id int auto_increment primary key,
                      salary int not null default 0,
                      uid int not null default 1,
    
                      constraint fk_priv_user foreign key (uid) references user(id),
                      unique(uid)
                  )charset=utf8;
    
                  insert into priv (salary, uid) values (2000, 1);
                  insert into priv (salary, uid) values (2800, 2);
                  insert into priv (salary, uid) values (3000, 3);
    
                  insert into priv (salary, uid) values (6000, 1);
                  ERROR 1062 (23000): Duplicate entry '1' for key 'uid'

三、多表联查

1. 左连接——>left join...on

  • 表示已left左边的表为主,会把左边的表中的信息全部显示,被join的表按照左边的表的数据一一对应显示。
  • 实例
    # 原表
    mysql> select * from department;
              +----+--------+
              | id | name   |
              +----+--------+
              |  1 | 研发部 |
              |  2 | 运维部 |
              |  3 | 前台部 |
              |  4 | 小卖部 |
              +----+--------+
              4 rows in set (0.07 sec)
    
              mysql> select * from userinfo;
              +----+--------+-----------+
              | id | name   | depart_id |
              +----+--------+-----------+
              |  1 | zekai  |         1 |
              |  2 | xxx    |         2 |
              |  3 | zekai1 |         3 |
              |  4 | zekai2 |         4 |
              |  5 | zekai3 |         1 |
              |  6 | zekai4 |         2 |
              +----+--------+-----------+
              6 rows in set (0.00 sec)
    
    # 联表查询:            
    
    # 错误写法
    mysql> select name  from userinfo left join department on depart_id = department.id;
    ERROR 1052 (23000): Column 'name' in field list is ambiguous
    
    # 正确写法
    mysql> select userinfo.name as uname, department.name as dname  from userinfo left join department on depart_id = department.id;
    
    # 查询结果
                  +--------+--------+
                  | uname  | dname  |
                  +--------+--------+
                  | zekai  | 研发部 |
                  | zekai3 | 研发部 |
                  | xxx    | 运维部 |
                  | zekai4 | 运维部 |
                  | zekai1 | 前台部 |
                  | zekai2 | 小卖部 |
                  +--------+--------+
                  6 rows in set (0.00 sec)

2. 右连接——>right join...on

  • 表示已right右边的表为主,会把右边的表中的信息全部显示,被join的表按照右边的表的数据一一对应显示。
  • 实例:
    mysql> insert into department (name) values ('财务部');
                  Query OK, 1 row affected (0.04 sec)
    
                  mysql>
                  mysql> select * from department;                     );
                  +----+--------+
                  | id | name   |
                  +----+--------+
                  |  1 | 研发部 |
                  |  2 | 运维部 |
                  |  3 | 前台部 |
                  |  4 | 小卖部 |
                  |  5 | 财务部 |
                  +----+--------+
                  5 rows in set (0.00 sec)
    
                  mysql> select * from userinfo;
                  +----+--------+-----------+
                  | id | name   | depart_id |
                  +----+--------+-----------+
                  |  1 | zekai  |         1 |
                  |  2 | xxx    |         2 |
                  |  3 | zekai1 |         3 |
                  |  4 | zekai2 |         4 |
                  |  5 | zekai3 |         1 |
                  |  6 | zekai4 |         2 |
                  +----+--------+-----------+
                  6 rows in set (0.00 sec)
    
                  mysql> select userinfo.name as uname, department.name as dname  from userinfo left join department on depart_id = department.id;
                  +--------+--------+
                  | uname  | dname  |
                  +--------+--------+
                  | zekai  | 研发部 |
                  | zekai3 | 研发部 |
                  | xxx    | 运维部 |
                  | zekai4 | 运维部 |
                  | zekai1 | 前台部 |
                  | zekai2 | 小卖部 |
                  +--------+--------+
                  6 rows in set (0.00 sec)
    
                  mysql> select userinfo.name as uname, department.name as dname  from userinfo right join department on depart_id = department.id;
                  +--------+--------+
                  | uname  | dname  |
                  +--------+--------+
                  | zekai  | 研发部 |
                  | zekai3 | 研发部 |
                  | xxx    | 运维部 |
                  | zekai4 | 运维部 |
                  | zekai1 | 前台部 |
                  | zekai2 | 小卖部 |
                  | NULL   | 财务部 |
                  +--------+--------+
                  7 rows in set (0.00 sec)

3. 内连接——>inner join...on

  • 实例:

    mysql> select * from department inner join userinfo on department.id=userinfo.depart_id;
                  +----+--------+----+--------+-----------+
                  | id | name   | id | name   | depart_id |
                  +----+--------+----+--------+-----------+
                  |  1 | 研发部 |  1 | zekai  |         1 |
                  |  1 | 研发部 |  5 | zekai3 |         1 |
                  |  2 | 运维部 |  2 | xxx    |         2 |
                  |  2 | 运维部 |  6 | zekai4 |         2 |
                  |  3 | 前台部 |  3 | zekai1 |         3 |
                  |  4 | 小卖部 |  4 | zekai2 |         4 |
                  +----+--------+----+--------+-----------+
                  6 rows in set (0.00 sec)

原文地址:https://www.cnblogs.com/Mcoming/p/11766291.html

时间: 2024-10-12 09:17:54

单表多表操作 联表查询的相关文章

Bootstrap 表单和图片 (内联表单,表单合组,水平排列,复选框和单选框,下拉列表,校验状态,添加额外的图标,控制尺寸,图片)

一.表单 基本格式 注:只有正确设置了输入框的 type 类型,才能被赋予正确的样式. 支持的输入框控件 包括:text.password.datetime.datetime-local.date.month.time.week. number.email.url.search.tel 和 color. <form> <div class="form-group"> <label>电子邮件</label> <input type=&

SQL Server 的表数据简单操作(表数据查询)

--表数据查询----数据的基本查询-- --数据简单的查询--select * | 字段名[,字段名2, ...] from 数据表名 [where 条件表达式] 例:use 商品管理数据库goselect * from 商品信息表select 商品编号,商品名称,产地 from 商品信息表selelct * from 商品信息表 where 产地='辽宁沈阳' --关键字辅助查询----1)distinct关键字 (用来消除查询结果中的重复行,使用时紧跟在select命令后)--select

oracle——数据表的相关操作——转移表空间

创建数据表; create table 表名 ( 列明1 数据类型1 [约束性条件], 列明1 数据类型1 [约束性条件], …… ) tablespace 表空间 create table student05 ( student_id number not null, student_name varchar2(20), student_age number, status varchar2(2), version number default 0 ) tablespace test sele

C#操作注册表全攻略

相信每个人对注册表并不陌生,在运行里面输入“regedit”就可以打开注册表编辑器了.这东西对Windows系统来说可是比较重要的,也是病 毒常常会光顾的地方,比如病毒和恶意软件常常会在注册表的启动项里面写入自己的启动键值来达到自启动的目的,有些病毒还会修改注册表里面来映像劫持杀毒软 件,这是破坏系统的第一步.同时,大多软件(软件的序列号和信息)和硬件信息.系统信息.安全模式等等设置都保存在这里,因此系统的健康在很大程度上要依 赖注册表的健康.       作为编程开发人员,我们有必要了解注册表

mysql(三) 数据表的基本操作操作

mysql(三) 数据表的基本操作操作 创建表,曾删改查,主键,外键,基本数据类型. 1. 创建表 create table 表名( 列名 类型 是否可以为空, 列名 类型 是否可以为空 )ENGINE=InnoDB DEFAULT CHARSET=utf8 例如: 类型解释: 是否可以为空: 是否可空,null表示空,非字符串 not null - 不可空 null - 可空 默认值设置 默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值 create table t

Django-orm:单表查询、基于对象和双下划线的多表操作、集合查询、分组查询、F查询和Q查询

############################################## 单表操作 ############################################## 简单查: models.User.objects.filter(id=3) # queryset对象,相当于一个列表,放了一个或多个User对象 models.User.objects.filter(id=3).first() # User对象,相当于只去了queryset对象中的第一个 增: 第一种

自动化运维Python系列之ForeignKey、relationship联表查询

一对多和多对多 数据库表结构设计是程序项目开发前的重要环节,后期数据库操作都是围绕着这个已经设计好的表结构进行,如果表结构设计有问题,整个程序项目就有存在需要整个推翻重构的风险... 数据库表结构除了简单的单表操作以外,还有一对多.多对多等. 一对多 基于SQLAlchemy我们可以先创建如下结构的2张表,然后来看看具体怎样通过外键ForeignKey或者relationship联表操作 创建表 from sqlalchemy.ext.declarative import declarative

表操作及字段查询

模型层 单表操作 1. all(): 查询所有结果 2. filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 3.get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误. 4. exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象.类似于取反. 5. values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列mod

SQL联表查询

数据库中最最常用的语法----select.简单的select语法很直白: select column from table where expression: 从((from)存储数据的地方(table)按照(where)一定的条件(expression)查找(select)我要的数据(column); 但是在实际工作中用到的比较多的往往还是多联表查询,所以在这里记下自己学习多联表查询的心得. 首先聊一聊笛卡尔积,这是几乎所有数据库书籍在讲多联表查询时第一个要讲的东西,我等P民也只能是把笛卡尔