MySQL-DQL之数据多表操作

文章目录

  • 一. 多表操作
    • 1. 表与表之间的关系
    • 2. 外键约束
    • 3. 创建外键约束表(一对多操作)
  • 二. 多表查询
    • 1. 多表查询
      • ① 交叉连接查询(基本不会使用-得到的是两个表的乘积) [了解](不要记住)
      • ② 交集运算:内连接查询(join)
      • ③ 差集运算:外连接查询
        • Ⅰ. 左外连接:(left join)
      • Ⅱ. 右外连接:(right join )
      • ④ 栗子
        • Ⅰ.栗子1(没有外键约束)
        • Ⅱ. 栗子2(有外键约束)
    • 2. 子查询
    • 3. 自连接查询
    • 4. case when
    • 5. 窗口函数

数据查询语言:简称DQL(Data Query Language)

一. 多表操作

实际开发中,一个项目通常需要很多张表才能完成。

例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系,接下来我们将在单表的基础上,一起学习多表方面的知识。
在这里插入图片描述

1. 表与表之间的关系

一对多关系:
常见实例:客户和订单,分类和商品,部门和员工。
一对多建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键。
在这里插入图片描述

2. 外键约束

现在我们有两张表“分类表”和“商品表”,为了表明商品属于哪个分类,通常情况下,我们将在商品表上添加一列,用于存放分类cid的信息,此列称为:外键。
在这里插入图片描述

此时“分类表category”称为:主表,“cid”我们称为主键。“商品表products”称为:从表,category_id称为外键。我们通过主表的主键和从表的外键来描述主外键关系,呈现就是一对多关系。

在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键。
指向谁,谁是主表

外键特点:
从表外键的值是对主表主键的引用。
从表外键类型,必须与主表主键类型一致。

外键优点:
在插入数据时,保证了数据的准确性。
在删除数据时,保证了数据的完整性。

在这里插入图片描述

从表中引用了主表中的数据,主表中数据不可被删除。
主表中没有数据,从表外键也无法被插入。

3. 创建外键约束表(一对多操作)

在这里插入图片描述
category分类表,为一方,也就是主表,必须提供主键cid
products商品表,为多方,也就是从表,必须提供外键category_id

创建分类表

create table category(cid varchar(32) primary key ,cname varchar(100)
);

创建商品表,添加约束

create table products(pid varchar(32) primary key ,pname varchar(40),price double,category_id varchar(32),constraint foreign key (category_id) references category(cid)
);

向分类表中添加数据

insert into category(cid, cname) values ('c001','服装');
insert into category(cid, cname) values ('c002','电器');

向商品表添加普通数据,没有外键数据,默认为null

insert into products(pid,pname) values ('p002','商品名称2');
insert into products(pid,pname,category_id) values ('p003','商品名称3',null);

向商品表添加普通数据,含有外键信息(category表中存在这条数据)

insert into products(pid,pname,category_id) values ('p001','商品名称1','c001');

向商品表添加普通数据,含有外键信息(category表中不存在这条数据) – 失败,异常

insert into products(pid,pname,category_id) values ('p004','商品名称4','c009');

删除指定分类(分类未被商品使用)

delete  from category where cid='c002';

删除指定分类(分类被商品使用) – 执行异常

delete  from category where cid='c001';

外键约束参考链接
on update cascade

二. 多表查询

在这里插入图片描述

1. 多表查询

① 交叉连接查询(基本不会使用-得到的是两个表的乘积) [了解](不要记住)

语法:select * from A,B;

这个结果有问题是错误的
在这里插入图片描述

② 交集运算:内连接查询(join)

显示内连接:

select * from A inner join B on 条件;
select * from A join B on 条件;

在这里插入图片描述

③ 差集运算:外连接查询

Ⅰ. 左外连接:(left join)

显示左连接:

select * from A left outer join B on 条件;
select * from A left join B on 条件;

在这里插入图片描述

Ⅱ. 右外连接:(right join )

显示右连接:

select * from A right outer join B on 条件;
select * from A right join B on 条件;

在这里插入图片描述

④ 栗子

Ⅰ.栗子1(没有外键约束)
  • 准备数据

    INSERT INTO hero VALUES(1, '鸠摩智', 9),(3, '乔峰', 1),(4, '虚竹', 4),(5, '段誉', 12);
    
    INSERT INTO kongfu VALUES(1, '降龙十八掌'),(2, '乾坤大挪移'),(3, '猴子偷桃'),(4, '天山折梅手');
    
  • 内连接(左表存在,右表也存在的数据被保留)

    SELECT hname,kname FROM hero INNER JOIN kongfu ON hero.kongfu_id = kongfu.kid; 
    

    在这里插入图片描述

  • 左连接(左表存在的数据被保留)

    SELECT hname,kname FROM hero LEFT OUTER JOIN kongfu ON hero.kongfu_id = kongfu.kid;
    

    在这里插入图片描述

  • 右连接(左表存在的数据被保留)

    SELECT hname,kname FROM hero RIGHT OUTER JOIN kongfu ON hero.kongfu_id = kongfu.kid
    

    在这里插入图片描述

Ⅱ. 栗子2(有外键约束)
  • 准备数据
    在这里插入图片描述

    CREATE TABLE category (cid VARCHAR(32) PRIMARY KEY ,cname VARCHAR(50)
    );
    
    CREATE TABLE products(pid VARCHAR(32) PRIMARY KEY ,pname VARCHAR(50),price INT,flag VARCHAR(2),    #是否上架标记为:1表示上架、0表示下架category_id VARCHAR(32),CONSTRAINT products_fk FOREIGN KEY (category_id) REFERENCES category (cid)
    );
    
    #分类
    INSERT INTO category(cid,cname) VALUES('c001','家电');
    INSERT INTO category(cid,cname) VALUES('c002','服饰');
    INSERT INTO category(cid,cname) VALUES('c003','化妆品');
    INSERT INTO category(cid,cname) VALUES('c004','奢侈品');
    #商品
    INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p001','联想',5000,'1','c001');
    INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p002','海尔',3000,'1','c001');
    INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p003','雷神',5000,'1','c001');
    INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p004','JACK JONES',800,'1','c002');
    INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p005','真维斯',200,'1','c002');
    INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p006','花花公子',440,'1','c002');
    INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p007','劲霸',2000,'1','c002');
    INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p008','香奈儿',800,'1','c003');
    INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p009','相宜本草',200,'1','c003');
    
  • 查询哪些分类的商品已经上架,内连接

    SELECT DISTINCT c.cname FROM category c INNER JOIN products p ON c.cid = p.category_id WHERE p.flag = '1';
    
  • 查询所有分类商品的个数
    COUNT(category_id)会过滤掉null

    SELECT cname,COUNT(category_id) FROM category c LEFT OUTER JOIN products p ON c.cid = p.category_id GROUP BY cname;

    COUNT(*)不会过滤掉null

    SELECT cname,COUNT(*) FROM category c LEFT OUTER JOIN products p ON c.cid = p.category_id GROUP BY cname;

2. 子查询

子查询:一条select语句结果作为另一条select语法一部分(查询条件,查询结果,表等)。
select …查询字段 … from … 表… where … 查询条件

栗子:查询“化妆品”分类上架商品详情

  • 子查询(作为查询条件)

    SELECT * FROM products p WHERE p.category_id = ( SELECT c.cid FROM category c WHERE c.cname='化妆品');
    
  • 作为另一张表

    SELECT * FROM products p , (SELECT * FROM category WHERE cname='化妆品') c WHERE p.category_id = c.cid;
    
  • 查询“化妆品”和“家电”两个分类上架商品详情

    SELECT * FROM products p WHERE p.category_id in ( SELECT c.cid FROM category c WHERE c.cname='化妆品' or c.cname='家电');

3. 自连接查询

在这里插入图片描述

自查询:左表和右表是同一个表,根据连接查询条件查询两个表中的数据
自查询(自连接)要起别名

  • 准备数据

    create table tb_areas(id varchar(30) not null primary key ,title varchar(30),pid varchar(30)
    );
    
    INSERT INTO test.tb_areas (id, title, pid) VALUES ('1', '广东省', 'null');
    INSERT INTO test.tb_areas (id, title, pid) VALUES ('2', '河南省', 'null');
    INSERT INTO test.tb_areas (id, title, pid) VALUES ('3', '深圳市', '1');
    INSERT INTO test.tb_areas (id, title, pid) VALUES ('4', '广州市', '1');
    INSERT INTO test.tb_areas (id, title, pid) VALUES ('5', '南山区', '3');
    INSERT INTO test.tb_areas (id, title, pid) VALUES ('6', '宝安区', '3');
    INSERT INTO test.tb_areas (id, title, pid) VALUES ('7', '越秀区', '4');
    INSERT INTO test.tb_areas (id, title, pid) VALUES ('8', '天河区', '4');
    

    在这里插入图片描述

    select  a.title,b.title,c.title from tb_areas as ainner join tb_areas as b on a.id=b.pidleft join tb_areas as c on b.id=c.pid
    where a.pid = 'null';
    
    select a.title,b.title,c.title from tb_areas aleft join tb_areas b on a.id=b.pidleft join tb_areas c on b.id=c.pid
    where b.id is not null and c.id is not null ;
    

自连接的问题, 需要注意 表要起别名, 如果自连接的次数比较多, 字段也要注意需要起别名

select a.province 省 , a. city 市 , disctrict.title 区 from(
select  p.title province, c.title city,c.id,c.pidfrom tb_areas as c
inner join  tb_areas as p on c.pid = p.id where p.title = '广东省') a
inner join tb_areas as disctrict on disctrict.pid = a.id;

起别名 AS 可以写, 也可以省略

4. case when

5. 窗口函数

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

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

相关文章

《经验分享 · 软考系统分析师》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…

宝塔面板Linux版本常用命令

宝塔面板(BT Panel)是一款简单易用的服务器管理工具,广泛应用于Linux服务器的管理。尽管宝塔提供了图形化界面,但在某些情况下,使用命令行操作更加高效。以下是宝塔面板Linux版本常用的命令,包括安装、管理…

ElasticSearch - 理解doc Values与Inverted Index倒排索引

文章目录 概述倒排索引:从图书馆的索引卡片谈起倒排索引的工作原理 docValues:从数据库的列式存储说起docValues的工作原理 docValues与倒排索引的对比两者的联系:组合使用,优化搜索与分析 小结 概述 在使用 Elasticsearch 进行大…

Acer宏碁Swift3笔记本S40-20,SF314-56G原厂Win10系统工厂模式安装包,带Recovery恢复还原

适用电脑型号:S40-20、SF314-56、SF314-56G(原装OEM预装系统) 链接:https://pan.baidu.com/s/1q77Br-hcmn9iJraGVVKQ7Q?pwdrw1r 提取码:rw1r Acer宏碁原装出厂windows10系统自带所有驱动、Office办公软件、出厂主题壁纸、系统属性专属联…

Python跳动的爱心

系列文章 序号直达链接表白系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4Python李峋同款可写字版跳动的爱心5Python流星雨代码6Python漂浮爱心代码7Python爱心光波代码8Python普通的玫瑰花代码9Python炫酷的玫瑰花代码10Python多…

极验决策引擎如何凭借独特优势,弯道超车传统风控?

前言 市场上的规则决策引擎产品众多,但大多局限于IP、设备、账号等层面,提供的是现成的风控标签和规则。然而,真正的风控,需要的不仅仅是标签和规则。 极验的业务规则决策引擎与众不同,这款决策引擎以界面流程编排为…

windows如何使用ssh连接kali

声明: 昨天晚上看了小羽老师的直播课,心血来潮自己也想搞一下这个ssh,中途安装遇到了不少问题,电脑也是重启了好多次,遇到bug就重启也是解决bug的一种方法. 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&…

SpringMvc完整知识点一

SpringMVC概述 定义 SpringMVC是一种基于Java实现MVC设计模型的轻量级Web框架 MVC设计模型:即将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。这种分离…

路由器、二层交换机与三层交换机的区别与应用

路由器、二层交换机和三层交换机是常见的网络设备,常常协同工作。它们都可以转发数据,但在功能、工作层级以及应用场景上存在差异。 1. 工作层级 三者在OSI模型中的工作层级不同: 路由器: 工作在 网络层(第三层&#…

(css)element中el-select下拉框整体样式修改

(css)element中el-select下拉框整体样式修改 重点代码(颜色可行修改) // 修改input默认值颜色 兼容其它主流浏览器 /deep/ input::-webkit-input-placeholder {color: rgba(255, 255, 255, 0.50); } /deep/ input::-moz-input-placeholder {color: rgba…

SEC_ASA 第一天作业

拓扑: 实验需求: 注意:在开始作业之前必须先读“前言”,以免踩坑!!!(☞敢点我试试) 按照拓扑图配置VLAN连接。 注意:ASA防火墙的 Gi0/1口需要起子接口&#x…

「Mac玩转仓颉内测版45」小学奥数篇8 - 排列组合计算

本篇将通过 Python 和 Cangjie 双语讲解如何计算排列与组合。这道题目旨在让学生学会使用排列组合公式解决实际问题,并加深对数学知识和编程逻辑的理解。 关键词 小学奥数Python Cangjie排列与组合 一、题目描述 编写一个程序,计算从 n 个不同元素中取…

Ungoogled Chromium127编译指南 Windows篇 - 获取源码(七)

1. 引言 在完成所有必要工具的安装和配置后,我们进入了Ungoogled Chromium编译过程的第一个关键阶段:获取源代码。本文将详细介绍如何正确获取和准备Ungoogled Chromium的源代码,为后续的编译工作打下基础。 2. 准备工作 2.1 环境检查 在…

人脸识别Adaface之libpytorch部署

目录 1. libpytorch下载2. Adaface模型下载3. 模型转换4. c推理4.1 前处理4.2 推理4.3 编译运行4.3.1 写CMakeLists.txt4.3.2 编译4.3.3 运行 1. libpytorch下载 参考: https://blog.csdn.net/liang_baikai/article/details/127849577 下载完成后,将其解…

Elasticsearch高性能实践

前言 本方案主要从运维层面分析es是实际生产使用过程中的参数优化,深入理解es各个名词及含义,深入分析es的使用过程中应注意的点,详细解释参数设置的原因以及目的,主要包括系统层面,参数层面。除此之外,优…

在idea中使用mysql(超详细)

一、连接mysql 在IDE开发工具中也是可以使用mysql的,这里以开发java常用的IntelliJ IDEA为例。 1. 打开idea,右上角有数据库侧边栏,打开侧边栏点击加号->数据源,可以看到支持很多数据库,选择mysql。 2. 首次使用需…

Python简化算法工具——“按位运算”

一、六种常见的“按位运算” 1.与(&)运算 运算规则:对两个整数对应的二进制位进行操作,当两个相应的二进制位都为1时,该位的结果才为1,否则为0。 a5 #0101b7 #0111print(a&b)#a&b0101#输出对…

Modbus转Profibus网关:打通多电机交流控制,打造自动化神器

在工业控制领域,Modbus和Profibus是两种非常常见的通信协议。Modbus由于其简单的结构、易于实现的特点被广泛应用在各种电子设备中,而Profibus则以其稳定性和实时性在大型自动化系统中占有一席之地。但是,有时候我们需要将这两种协议进行转换…

C++重点和练习

作业1&#xff1a;实现类中有类的几个特殊成员函数 #include <iostream>using namespace std;class Person {string name;int *age; public:Person():name("none"),age(new int(0)){}Person(int age):age(new int(age)){}Person(string name,int age):name(na…

亚马逊云科技用生成式AI,向开发的复杂性动手了

生成式 AI、分布式扩展功能全面进化&#xff0c;还降价了。 同一天的发布&#xff0c;完全不同的方向。 今天凌晨&#xff0c;云计算巨头亚马逊云科技的 re:Invent 与大号创业公司 OpenAI 的发布「撞了车」。后者公布了一系列生成式 AI 应用&#xff0c;价格更贵、性能更强大&a…