MySQL数据库基础(三):多表查询,子查询,开窗函数

news2024/11/27 12:37:41

十一、多表查询(重点、难点)

表与表之间的关系

在SQL语句中,数据表与数据表之间,如果存在关系,一般一共有3种情况:

① 一对一关系(高级)

比如有A、B两张表,A表中的每一条数据,在B表中有一条唯一的数据与之对应。

用户表user

user_id(用户编号)

账号username

密码password

001

admin

admin888

002

itheima

123456

用户详情表user_items

user_id(用户编号)

真实姓名

年龄

联系方式

001

张三

16

10086

002

李四

18

10010

我们把用户表与用户详情表之间的关系就称之为一对一关系。

② 一对多关系(重点)

比如有A、B两张表,A表中的每一条数据,在B表中都有多条数据与之对应,我们把这种关系就称之为一对多关系 产品分类表

分类id编号

分类名称

1

手机

2

电脑

产品信息表

产品id编号

产品名称

产品价格

所属分类id编号

1

Apple iPhone 13

6799.00

1

2

Redmi Note 9

3499.00

1

我们把产品分类表与产品表之间的关系就称之为一对多关系。

③ 多对多关系(高级)

用户表

用户编号

登录账号

登录密码

1

admin

admin888

2

itheima

123456

权限表

权限id编号

权限名称

1

增加

2

删除

3

修改

4

查询

虽然从以上图解来看,两者之间好像没有任何联系,但是两者之间其实是有关系的,这种关系需要通过一张临时表进行呈现。

每个用户,应该有对应的权限,admin账号可以做增删改查,itheima账号可以做查询

反过来

每个权限都应该对应多个用户,查询权限 => admin/itheima

中间表 :用户_权限表

用户id编号

权限的id编号

1(admin)

1(增加)

1

2(删除)

1

3(修改)

1

4(查询)

2

4(查询)

交叉连接(了解)

没有意义,但是它是所有连接的基础。其功能就是将表1和表2中的每一条数据进行连接。

结果:

字段数 = 表1字段 + 表2的字段

记录数 = 表1中的总数量 * 表2中的总数量(笛卡尔积)

 
 

select * from students cross join classes;

select * from students, classes;

1、内连接

☆ 连接查询的介绍

连接查询可以实现多个表的查询,当查询的字段数据来自不同的表就可以使用连接查询来完成。 连接查询可以分为:

  1. 内连接查询

  2. 左外连接查询

  3. 右外连接查询

  4. 自连接查询(自己查询自己)

☆ 内连接查询

查询两个表中符合条件的共有记录

内连接查询语法格式:

 
 

select 字段 from 表1 inner join 表2 on 表1.字段1 = 表2.字段2

说明:

  • inner join 就是内连接查询关键字

  • on 就是连接查询条件

例1:使用内连接查询学生表与班级表:

 
 

select * from students as s inner join classes as c on s.cls_id = c.id;

☆ 小结

  • 内连接使用inner join .. on .., on 表示两个表的连接查询条件

  • 内连接根据连接查询条件取出两个表的 “交集”

2、左外连接

☆ 左连接查询

以左表为主根据条件查询右表数据,如果根据条件查询右表数据不存在使用null值填充

左连接查询语法格式:

 
 

select 字段 from 表1 left join 表2 on 表1.字段1 = 表2.字段2

说明:

  • left join 就是左连接查询关键字

  • on 就是连接查询条件

  • 表1 是左表

  • 表2 是右表

例1:使用左连接查询学生表与班级表:

 
 

select * from students as s left join classes as c on s.cls_id = c.id;

☆ 小结

例1:使用右连接查询学生表与班级表:

 
 

select * from students as s right join classes as c on s.cls_id = c.id;

☆ 小结

4、自连接查询(扩展)

自连接查询:数据表自己连接自己,前提:连接操作时必须为数据表定义别名!

左表和右表是同一个表,根据连接查询条件查询两个表中的数据。

两个实际的工作场景,求省市区信息,求分类导航信息

cid

name

pid

1

图书

null

2

童书

1

3

中国儿童文学

2

地域:area

pid 全称 parent id(父级ID编号),如果pid值为null代表本身就是父级,如果pid是一个具体的数值,则代表其属于子级

例1:查询省的名称为“广东省”的所有城市

创建areas表:

 
 

use db_itheima;
create table tb_area(
aid int not null AUTO_INCREMENT,
atitle varchar(20),
pid int,
primary key(aid)
) default charset=utf8;

执行sql文件给areas表导入数据:

 
 

insert into tb_area values (null, '广东省', null),(null, '山西省', null),(null, '深圳市', 1), (null, '广州市', 1);

自连接查询的用法:

 
 

select c.id, c.title, c.pid, p.title from areas as c inner join areas as p on c.pid = p.id where p.title = '广东省';

说明:

☆ 小结

十二、子查询(三步走)

  • 左连接使用left join .. on .., on 表示两个表的连接查询条件

  • 左连接以左表为主根据条件查询右表数据,右表数据不存在使用null值填充。

  • 3、右外连接

    ☆ 右连接查询

    以右表为主根据条件查询左表数据,如果根据条件查询左表数据不存在使用null值填充

    右连接查询语法格式:

     
     

    select 字段 from 表1 right join 表2 on 表1.字段1 = 表2.字段2

    说明:

  • right join 就是右连接查询关键字

  • on 就是连接查询条件

  • 表1 是左表

  • 表2 是右表

  • 右连接使用right join .. on .., on 表示两个表的连接查询条件

  • 右连接以右表为主根据条件查询左表数据,左表数据不存在使用null值填充。

  • 自连接查询必须对表起别名

  • 自连接查询就是把一张表模拟成左右两张表,然后进行连表查询。

  • 自连接就是一种特殊的连接方式,连接的表还是本身这张表

1、子查询(嵌套查询)的介绍

在一个 select 语句中,嵌入了另外一个 select 语句, 那么被嵌入的 select 语句称之为子查询语句,外部那个select语句则称为主查询.

主查询和子查询的关系:

子查询是嵌入到主查询中

子查询是辅助主查询的,要么充当条件,要么充当数据源(数据表)

子查询是可以独立存在的语句,是一条完整的 select 语句

十三、外键约束(扩展)

2、子查询的使用

例1. 查询学生表中大于平均年龄的所有学生:

需求:查询年龄 > 平均年龄的所有学生

前提:

① 获取班级的平均年龄值

② 查询表中的所有记录,判断哪个同学 > 平均年龄值 第一步:写子查询

 
 

select avg(age) from students;

第二步:写主查询

 
 

select * from students where age > (平均值);

第三步:第一步和第二步进行合并

 
 

select * from students where age > (select avg(age) from students);

例2. 查询tb_goods产品表中具有分类信息的产品

需求:查询产品表中具有分类信息的产品(没有与之对应分类信息的产品不显示)

前提:① 查询分类表中,到底有哪些分类(获取cid编号)

② 到产品表中进行判断,判断这个商品的cid编号与①中的是否相等 第一步:编写子查询

 
 

select cid from tb_category;

第二步:编写主查询

 
 

select * from tb_goods where cid in (所有分类cid编号)

第三步:把主查询和子查询合并

 
 

select * from tb_goods where cid in (select cid from tb_category);

例3. 查找年龄最小且成绩最低的学生:

第一步:获取年龄最小值和成绩最小值

 
 

select min(age), min(score) from student;

第二步:查询所有学员信息(主查询)

 
 

select * from students where (age, score) = (最小年龄, 最少成绩);

第三步:把第一步和第二步合并

 
 

select * from students where (age, score) = (select min(age), min(score) from students);

注:数据表中必须有这样一条记录,否则可能查询不到结果,重点练习子查询返回多个结果情况。

3、小结

子查询是一个完整的SQL语句,子查询被嵌入到一对小括号里面 掌握子查询编写三步走

十三、外键约束(扩展)

主键:primary key

外键:foreign key(应用场景:在两表或多表关联的时候设置的,用于标志两个表之间的关联关系)

 
 

create table 数据表名称(
字段名称 字段类型 字段约束[5种情况]
) default charset=utf8;

① 主键约束primary key

② 默认值约束default

③ 非空约束not null

④ 唯一约束unique key

⑤ 外键约束foreign key

原则:在一张表中,其是主键。但是在另外一张表中,其是从键(非主键),但是这个字段是两张表的关联字段。

1、外键约束作用

外键约束:对外键字段的值进行更新和插入时会和引用表中字段的数据进行验证,数据如果不合法则更新和插入会失败,保证数据的有效性。

dage表:

id编号(主键)

name姓名

1

陈浩南

2

乌鸦哥

xiaodi表:

id编号(主键)

name姓名

dage_id(外键)

1

山鸡

1

2

大天二

1

3

乌鸦的小弟

2

外键设计原则:保证两张表的关联关系,保证数据的一致性。在选择时,一般在一个表中时关联字段,在另外一个表中是主键,则这个字段建议设置为外键。

2、对于已经存在的字段添加外键约束

 
 

-- 为cls_id字段添加外键约束
alter table 数据表 add foreign key(外键字段) references 数据表(主键)
[on delete cascade| set null] [on update cascade | set null];

3、在创建数据表时设置外键约束

 
 

-- 创建一个大哥表
create table dage(
id int not null auto_increment,
name varchar(20),
primary key(id)
) default charset=utf8;
-- 添加测试数据
insert into dage values (null, '陈浩南');
insert into dage values (null, '乌鸦');


-- 创建一个小弟表
create table xiaodi(
id int not null auto_increment,
name varchar(20),
dage_id int,
primary key(id)
) default charset=utf8;
-- 把dage_id设置为主键
alter table xiaodi add foreign key(dage_id) references dage(id) on delete cascade;
-- 插入测试数据
insert into xiaodi values (null, '山鸡', 1);
insert into xiaodi values (null, '大天二', 1);
insert into xiaodi values (null, '乌鸦的小弟', 2);


-- 测试外键
delete from dage where id = 2;
select * from xiaodi; -- 看看乌鸦的小弟是否还存在

-- 删除外键
show create table xiaodi; -- 查看外键名称(如xiaodi_ibfk_1)
alter table xiaodi drop foreign key xiaodi_ibfk_1;

4、删除外键约束

 
 

-- 需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
show create table 数据表;

-- 获取名称之后就可以根据名称来删除外键约束
alter table 数据表 drop foreign key 外键名;

十四、索引[了解]

① 编写SQL ② SQL优化(查询数据把查询时间缩短)

TB级别,10s => 0.01s

1、索引概述

索引作用: 快速检索数据(提高查询效率),InnoDB引擎其底层主要是使用B+ Tree结构

2、普通索引使用

主键就是一个索引,比如百万条数据,没有主键索引,查询可能需要3-5s,如果我们添加了主键索引且刚好,要查询的字段就是主键,则可以缩短到零点零几秒。

备注:主键、外键、唯一键其实也是索引

创建索引: create index index_cname on category(cname); create index index_cname on category(cname(20));

修改表添加索引: alter table category add index index_cname(cname(20));

查询索引: show index from category;

删除索引: drop index index_cname on category;

查看所有库或者表的索引:

 
 

# 了解: mysql 是系统自带的数据库。innodb_index_stats 表记录 innodb 引擎(数据库核心) 的 索引状态.
# 查看数据库的所有索引:
select *
from mysql.innodb_index_stats where database_name="bigdata_db";

# 查看数据表的所有索引:
select *
from mysql.innodb_index_stats where database_name="bigdata_db" and table_name="products";

3、唯一索引使用

 
 

create unique index index_cname on category(cname(20));
alter table category add unique index index_cname(cname(20));

 

-- 开启运行时间监测:
set profiling=1;
-- 查找第1万条数据ha-99999
select * from tb_index where title='ha-99999';
-- 查看执行的时间:
show profiles;
-- 给title字段创建索引:
alter table tb_index add index (title);
-- 再次执行查询语句
select * from test_index where title='ha-99999';
-- 再次查看执行的时间
show profiles;

4、索引使用注意

 
  • 创建索引

  • 删除索引

  • 索引不是越多越好. 索引使用应该注意以下问题:

  • 磁盘空间消耗

  • 创建索引和维护索引的时间消耗

  • 经常增删改数据,索引需要动态维护,效率低下。

  • 不经常查询的字段不需要创建索引

  • 大部分值相同的字段不需要创建索引

  • 扩展:

  • 开启mysql时间检测: set profiling=1;

  • 查看sql语句执行时间: show profiles;

十五、开窗函数(mysql 8.0后新的)

1、数据准备

 
 

create table employee (
empid int,
ename varchar(20) ,
deptid int,
salary decimal(10,2)
) default charset=utf8;

insert into employee values(1,'刘备',10,5500.00);
insert into employee values(2,'赵云',10,4500.00);
insert into employee values(2,'张飞',10,3500.00);
insert into employee values(2,'关羽',10,4500.00);

insert into employee values(3,'曹操',20,1900.00);
insert into employee values(4,'许褚',20,4800.00);
insert into employee values(5,'张辽',20,6500.00);
insert into employee values(6,'徐晃',20,14500.00);

insert into employee values(7,'孙权',30,44500.00);
insert into employee values(8,'周瑜',30,6500.00);
insert into employee values(9,'陆逊',30,7500.00);

2、开窗函数使用

格式:

 

select *,
row_number() over (partition by deptid order by salary) as row_n
from employee;

# select *,
# row_number() over (order by salary) as row_n
# from employee;

# 1. 查询每一个部门的薪资排名
select *,
row_number() over (partition by deptid order by salary) as row_n,
rank() over (partition by deptid order by salary) as rank_n,
dense_rank() over (partition by deptid order by salary) as drank_n
from employee;

# 开窗函数:
# row_number:显示排序后的行数
# rank: 显示名次,可以并列排名,下一个排名会跳跃并列个数
# dense_rank: 显示名次,可以并列排名,下一个排名不会跳跃

# 2. 查询每个部门薪资排名第2的员工;
select * from
(select
*,
dense_rank() over (partition by deptid order by salary desc) as row_n
from employee) c where c.row_n=2;

 
 
 

select
*,
开窗函数() over(partition by 分组字段 order by 排序字段),
...
from 表名;

 

  • partition by :相当于分组group by

  • order by :相当于前面的order by

  • 使用:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/720179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多肽试剂:143120-27-8,Cyclo(-D-Tyr-Arg-Gly-Asp-Cys(carboxymethyl)-OH) sulfoxide

试剂基团反应特点(Reagent group reaction characteristics): 环肽试剂Cyclo(-D-Tyr-Arg-Gly-Asp-Cys(carboxymethyl)-OH) sulfoxide,陕西新研博美生物科技有限公司多肽合成、定制多肽、同位素标记肽、人工胰岛素、磷酸肽、生物素…

Python split()函数使用详解,Python分割字符串

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 split 1、不指定分隔符2、分隔符的类型3、指定分隔次数4、分隔的结果 split() 可…

你真的不想知道怎么用ai绘画图片生成图片吗?

亲爱的二次元迷们,你是否曾经梦想过能够画出自己心中的二次元角色,让他们跃然纸上、生动活泼地展现在世人面前?但是,面对空白的画板和一支笔,我们有时会感到无从下手,毫无艺术细胞可言。不要失望&#xff0…

Dlib —— 对视频流进行人脸识别(附C++部分源码、完整源码下载)

照片效果 视频效果 注意:Dlib检测人脸在Release版耗时与CPU有关,本人I7 10代约100ms左右,这里本人将人脸检测用Yolov5对人脸简单抠图训练后 使用yolov5推理检测人脸,之后将检测到的人脸输入给Dlib做特征,发现人脸特征部分耗时也较…

基础实验篇 | uORB消息读写与自定义实验(一)

导读 uORB是PX4/Pixhawk系统中非常重要且关键的模块之一,是用于无人机模块间通信的协议机制。本篇将详细介绍uORB并详细拆解uORB消息读写与自定义实验(一)。 基础实验篇 | uORB消息读写与自定义实验(一) ect Request Broker,微对…

7、动手学深度学习——卷积神经网络:基础部件+LeNet

1、图像卷积 1. 互相关运算 严格来说,卷积层是个错误的叫法,因为它所表达的运算其实是互相关运算(cross-correlation),而不是卷积运算。在卷积层中,输入张量和核张量通过(互相关运算)产生输出张量。 首先…

python 中禁用 SettingWithCopyWarning

最近代码中出现了这个warn,但是我确信我已经把所有的df赋值都改成loc了,依旧会出现,只有把这个warn禁了。 import pandas as pd import warnings# 禁用 SettingWithCopyWarning 警告 warnings.filterwarnings("ignore", categorypd…

闲人闲谈PS之四十三——标准程序的陷阱

惯例闲话:7月,闲人家乡的水蜜桃成熟了,闲人很喜欢吃桃子,可惜经常出门在外,经常错过了水果最好的季节,这次委托家人邮寄了几箱,果然还是家乡的桃子好吃。回顾这几年,错过了不仅仅是水…

数据库sql 根据身份证计算年龄段mysql、oracle

数据库sql根据身份证计算年龄段 mysql: SELECTage,count(*) numFROM(SELECTCASEWHEN TIMESTAMPDIFF(YEAR,DATE(substring(id_card,7,8)),CURDATE())<35 THEN 35岁以下WHEN TIMESTAMPDIFF(YEAR,DATE(substring(id_card,7,8)),CURDATE()) > 35AND TIMESTAMPDIFF(YEAR,DATE…

deque容器语法

文章目录 deque容器deque容器基本概念功能&#xff1a;deque 的实现细节deque与vector底层区别&#xff1a; deque构造函数功能描述&#xff1a;函数原型&#xff1a; deque元素访问deque赋值操作功能描述&#xff1a;函数原型&#xff1a; deque大小操作功能描述&#xff1a;函…

哪些期货公司招居间人,期货居间人的红利期时代已过,该何去何从

2021年9月10日&#xff0c;中国期货业协会发布了关于发布《期货公司居间人管理办法 (试行)》的通知&#xff0c;《期货公司居间人管理办法(试行)》正式出台。 根据通知&#xff0c;期货公司仅能与经有关金融监管部门批准设立的证券公司等金融机构开展居间合作。现在的法人居间绝…

【stable-diffuision-webui】controlnet制作动漫二维码(丐版)

主要参考 原作者的博文&#xff1a;AI生成可扫码图像 — 新 ControlNet 模型展示 光照生成模型C站说明&#xff1a;https://civitai.com/models/80536/lighting-based-picture-control-controlnet 扩展阅读&#xff1a;https://aigc.ioclab.com/sd-showcase/light_controlnet.…

Sentieon | 每周文献-Agrigenomics-第四期

农业系列文章-1 标题&#xff08;英文&#xff09;&#xff1a;Genomic footprints of sorghum domestication and breeding selection for multiple end uses标题&#xff08;中文&#xff09;&#xff1a;高粱驯化的基因组足迹和多种最终用途的育种选择发表期刊&#xff1a;《…

vue3中使用jsx

一、使用vue-cli创建的项目中使用jsx语法 安装Vue 3&#xff1a;使用Vue CLI创建一个新项目或通过npm安装Vue。 配置Vue JSX插件&#xff1a;在创建的项目中&#xff0c;找到 babel.config.js 文件&#xff0c;添加以下插件配置&#xff1a; module.exports {presets: [vue…

CentOS Linux MySQL 数据库 的安装方法

一、简单了解MySQL数据库的体系结构 &#xff08;一&#xff09;MySQL架构图 &#xff08;二&#xff09;MySQL体系结构&#xff1a;连接层、服务层、引擎层、存储层 1、连接层--主要职责&#xff1a;身份认证&#xff0c;连接管理&#xff0c;获取权限信息 &#xff08;1&am…

No11.精选前端面试题,享受每天的挑战和学习

文章目录 JS数组去重的几个方法讲下es6新增symbol 数据类型v-model原理是什么vue响应式原理vue中的data 为什么是个函数&#xff1f;前端有几种缓存方式 JS数组去重的几个方法 在JavaScript中&#xff0c;可以使用几种方法对数组进行去重&#xff1a; 使用Set&#xff1a;Set…

每日汇评:美联储会议纪要是否能确认黄金的看涨楔形?

1、在美国独立日清淡的交易中&#xff0c;黄金价格创下了一周以来的新高&#xff1b; 2、在美联储会议纪要之前&#xff0c;美元利用了对经济衰退的担忧和中美科技之争&#xff1b; 3、黄金需要日线收在1922美元上方才能确认看涨楔形&#xff0c;但看跌的RSI值得谨慎&#xf…

png转svg图片免费

svg免费转换网站 https://vectr.com/design/editor/c232c8cb-5eb8-4bae-b302-25cb94a8f737 操作步骤 1.上传png或者其他格式图片 2.点击导出文件 3.选择导出格式为svg和其他配置参数 4.打开下载好的svg图片 5.在编辑器中看svg图片

短视频矩阵系统源码自研+开发技术文档

一、短视频矩阵系统源码自研&#xff08;站在开发者交付分析&#xff09; 目录 一、短视频矩阵系统源码自研&#xff08;站在开发者交付分析&#xff09; 二、 短视频矩阵系统需要开发的前提语言框架技巧&#xff1a;NGINX&#xff0c;PHP7.4&#xff0c;MySQL5.7&#xff0…

多个微信号如何管理?

很多公司都在发愁这几个问题&#xff1a; 1、拥有多个微信号&#xff0c;不想管理多台手机&#xff0c;想将所有微信号进行统一管理 2、想用软件来代替传统的营销体系&#xff0c;安全性上也要有保障 3、用人成本太大与公司的效益不成正比 4、多个账号发圈不方便&#xff0…