玩转MySQL(4)---多表关联

一、首先,我们可以查看数据库的各种变量:

1.SHOW VARIABLES 查看数据库的变量

2.查看当前数据库的编码

SHOW VARIABLES WHERE variable_name LIKE 'character%';

3.解决中文乱码,如下三个编码保持一致就可以。

character_set_client、character_set_connection、character_set_results

二、子查询

4.case-when then end

SELECT sno,sname,age,saddress,(CASE sex WHEN '0' THEN '女' WHEN '1' THEN '男' ELSE '泰国' END)AS

性别 FROM sstud;

 

5.无关子查询

//查询具有相同年龄的人 --每年年龄段只显示一个代表

SELECT * FROM sstud GROUP BY age HAVING COUNT(age)>=2;

SELECT * FROM sstud WHERE age IN(

SELECT age FROM sstud GROUP BY age HAVING COUNT(age)>=2

);

 

//再加条件 age>20
SELECT * FROM sstud WHERE age IN(

SELECT age FROM sstud GROUP BY age HAVING COUNT(age)>=2 AND age>20

);

 

6.相关子查询

SELECT xs.name,xs.age, th.name, count(*) as c FROM sstud as xs, teacher as th WHERE age IN(

SELECT age FROM sstud where th.age>45 and c>2 GROUP BY age HAVING COUNT(age)>=2;

);

 

三、表与表之间的关系

数据库实体间有三种对应关系:一对一,一对多,多对多。

(一)、一对一

比如:夫妻就是一对一的关系(以下以夫妻表为例):

 

方式1:用两个独立的表来实现---项目用得更多的方式

CREATE TABLE wm(
  id INT PRIMARY KEY,
  NAME VARCHAR(10),
  sex CHAR(1)
);


CREATE TABLE mm(
  id INT PRIMARY KEY,
  NAME VARCHAR(10),
  sex CHAR(1),

  wid INT UNIQUE,   注:外键,这一句表明wid属性与wm表中的id属性是一对一的,若没有这句则是一对多的。

  CONSTRAINT mm_fk FOREIGN KEY(wid) REFERENCES wm(id)  注:设置外键
);

查询夫妻信息
SELECT mm.name AS 丈夫, wm.name AS 妻子 FROM mm, wm WHERE mm.wid=wm.id


 

方式2:用一个物理表来实现,同时创建两个虚拟表(视图)
需要两个表。当然做项目时为了省空间,通常只建一个表,如果要实现一对一的查询,可以建两个视图。示例如下:
1)建物理表,初始化数据
CREATE TABLE person(
   id INT,
   NAME VARCHAR(10),
   sex CHAR(1),
   wife INT,
   husband INT
);
INSERT INTO person VALUES(1,'小花','0',0,3);
INSERT INTO person VALUES(2,'玉芬','0',0,4);
INSERT INTO person VALUES(3,'张三','1',1,0);
INSERT INTO person VALUES(4,'李四','1',2,0);
INSERT INTO person VALUES(5,'王五','1',0,0);


2) 建立两个视图
create view women as select * from person where sex='0';

create view men as select * from person where sex='1';

3) 查询夫妻信息
//旧版本
SELECT women.name AS 妻子, men.name AS 丈夫 FROM women, men WHERE women.husband = men.id;

---------------------------------
//采用内联接--98以后的新方式--效率更高
SELECT women.name AS 妻子, men.name AS 丈夫 FROM women INNER JOIN men ON women.husband = men.id;

 

这里就要讲到 关联了:

INNER JOIN(内联):两个表a,b 相连接,取出符合连接条件的字段

LEFT JOIN(左联):先返回左表的所有行,再加上符合连接条件的匹配行

RIGHT JOIN(右联):先返回右表的所有行,再加上符合连接条件的匹配行

1、内连接——最常用 

定义:仅将两个表中满足连接条件的行组合起来作为结果集。

在内连接中,只有在两个表中匹配的行才能在结果集中出现 

关键词:INNER JOIN

格式:SELECT 列名表 FROM 表名1 [INNER] JOIN 表名2 ON或WHERE 条件表达式 
 

说明: 
(1)列名表中的列名可以出自后面的两个表,但如果两个表中有同名列,应在列名前标明出处,格式为:表名.列名

(2)若连接的两个表名字太长,可以为它们起个别名。 格式为:表名 AS 别名 

(3)INNER是默认方式,可以省略

 

 

2、左连接

定义:在内连接的基础上,还包含左表中所有不符合条件的数据行,并在其中的右表列填写NULL

关键字:LEFT JOIN

注意: 

当在内连接查询中加入条件是,无论是将它加入到join子句,还是加入到where子句,其效果是完全一样的,但对于外连接情况

就不同了。

当把条件加入到 join子句时,SQL Server、Informix会返回外连接表的全部行,然后使用指定的条件返回第二个表的行。

 

3、右连接

定义:在内连接的基础上,还包含右表中所有不符合条件的数据行,并在其中的左表列填写NULL

关键字:RIGHT JOIN

 

4、完全连接 (mysql不支持)

定义:在内连接的基础上,还包含两个表中所有不符合条件的数据行,并在其中的左表、和右表列填写NULL

关键字:FULL JOIN

 

5.外连接(mysql不支持)

关键字:OUTTER JOIN

关联,可理解成把几个合成一个新的表,然后在新表中进行查询

 

(二)、一对多

数据库设计分析
※案例:一个人可以拥有多辆汽车,要求查询出某人所拥有的所有汽车。
方案一(差的设计):
编号   姓名  性别   年龄   汽车编号   车型  排量  价格
P001  Jack   男     25     C001     BMW    12L   80w
P001  Jack   男     25     C002     Benz   12L   100w
P001  Jack   男     25     C003     Benz   12L   100w
P002  Tom    男     25     C004     BMW    12L   80w
P002  Tom    男     25     C005     Benz   12L   100w
P003  Rose   女     25     C006     Benz   12L   100w

方案二(好的设计):
1)把一方单独建个表
编号   姓名  性别   年龄
P001  Jack   男     25
P002  Tom    男     25
P003  Rose   女     25
2)把多方也建个表(依赖一方,通过外键--补一个字段)
外键:位于依赖一方,它是被依赖一方是主键
汽车编号   车型  排量  价格    车主
 C001     BMW    12L   80w    P001
 C002     Benz   12L   100w   P001
 C003     Benz   12L   120w   P001
 C004     BMW    12L   80w    P002
 C005     Benz   12L   100w   P002
 C006     Benz   12L   100w   P003

3) 代码实现
CREATE TABLE person2(
   id varchar(32) primary key,
   NAME VARCHAR(30),
   sex CHAR(1),
   age INT
);
INSERT INTO person2 VALUES('P1001','小花','0',25);
INSERT INTO person2 VALUES('P1002','张三','1',22);
INSERT INTO person2 VALUES('P1003','Jack','1',24);
INSERT INTO person2 VALUES('P1004','Rose','0',25);

CREATE TABLE car(
   id varchar(32) primary key,
   NAME VARCHAR(30),
   price numeric(10,2),
   pid varchar(32),  
   /*为字段pid定义一个外键约束(来自person2表的字段id)*/
   constraint car_fk foreign key(pid) references person2(id)
);
INSERT INTO car VALUES('C001','BMW',80.5,'P1001');
INSERT INTO car VALUES('C002','Benz',100,'P1001');
INSERT INTO car VALUES('C003','BMW',120.05,'P1001');
INSERT INTO car VALUES('C004','Benz',88.5,'P1002');
INSERT INTO car VALUES('C005','QQ',8.5,'P1002');
INSERT INTO car VALUES('C006','BIKE',0.5,'P1003');

 1.哪些人有哪些车 

SELECT * FROM person2 INNER JOIN car ON person2.id=car.pid;

SELECT person2.NAME,car.id,car.NAME,car.price FROM  person2 INNER JOIN car ON person2.id=car.pid WHERE car.price>50;

 

2.Mike的车辆信息

SELECT person2.NAME,person2.age,car.id,car.NAME,car.price FROM  person2 LEFT JOIN car ON person2.id=car.pid WHERE person2.NAME='Mike'

 

3.哪些人没有车

SELECT person2.NAME,person2.age,car.NAME FROM  person2 LEFT JOIN car ON person2.id=car.pid WHERE car.NAME IS NULL;

 

4.哪些人至少有两辆车

//新版
SELECT person2.NAME,car.id FROM person2 INNER JOIN car ON person2.id=car.pid GROUP BY person2.NAME HAVING COUNT(*)>=2;

//旧版
SELECT NAME FROM person2 WHERE id IN('P1001','P1002');
SELECT NAME FROM person2 WHERE id IN( SELECT pid FROM car GROUP BY pid HAVING COUNT(*)>1 );

 

(三)、多对多

数据库设计分析

※案例:一个人可以选择多门课程,一门课程又可以被很多人选择。

方案一(差的设计):
1)学生表
编号   姓名  性别   年龄  电话 ...
P001  Jack   男     25
P002  Tom    男     25
P003  Rose   女     25
--------------------------
2)课程表
编号   名称   教材  学分...  学生
S001   Java   ...  ......   P001
S001   Java   ...  ......   P002
S001   Java   ...  ......   ...
S002   数据库  ... ......   P001
S002   数据库  ... ......   P002
......

方案二(好的设计:两个实体表+一个关系表):
1)学生表(独立)---实体
编号   姓名  性别   年龄  电话 ...
P001  Jack   男     25
P002  Tom    男     25
P003  Rose   女     25
2)课程表(独立)---实体
编号   名称   教材  学分...
S001   Java   ...  ......
S002   数据库  ... ......
S003   XML   ... ......
3)选课表(专为体现多对多的关系而新增的表)--关系
课程编号  学生编号
S001      P001
S001      P002
...
S002      P002
S002      P003
...
S003      P001
...

 外键      外键
   |        |
   |━━━━|  
       |
     联合主键

 

4) 代码实现

CREATE TABLE stud2(
   id varchar(32) primary key,
   NAME VARCHAR(30),
   age INT
);


CREATE TABLE ject(
   id varchar(32) primary key,
   NAME VARCHAR(30)
);


CREATE TABLE sj(

studid varchar(32),

subjectid VARCHAR(32)

);

//单独添加约束(注意顺序: 要先添加联合主键,再添加外键)

//创建联合主键

ALTER TABLE sj ADD CONSTRAINT pk_sj PRIMARY KEY(studid,subjectid);

//创建两个外键

alter table sj add constraint fk_stud foreign key(studid) references stud(id);

alter table sj add constraint fk_subj foreign key(subjectid)references ject(id);

//删除外键---先添加外键再添加联合主键时,不行。删除外键,重来

ALTER TABLE sj DROP FOREIGN KEY fk_stud;

ALTER TABLE sj DROP FOREIGN KEY fk_subj;

 

1.查询哪些人选了哪些课
//92标准

select stud.name,ject.name  from stud,ject,sj  where stud.id=sj.studid and ject.id = sj.subjectid;

//96标准
select stud.name,ject.name  from
    stud inner join sj  on stud.id=sj.studid
         inner join ject on  ject.id = sj.subjectid;

 

2查询哪些人没有选课

//92标准

SELECT  stud.name FROM stud WHERE stud.id NOT IN (SELECT  studid FROM sj ); 

//96标准--左关联

SELECT  stud.name FROM stud LEFT JOIN sj  ON stud.id=sj.studid LEFT JOIN ject ON  ject.id = sj.subjectid

WHERE ject.NAME IS NULL;

//3查询哪些课程没人选

//96标准--左关联

SELECT  ject.name FROM
    ject LEFT JOIN sj  ON ject.id=sj.subjectid
         LEFT JOIN stud ON  stud.id = sj.studid
    WHERE stud.NAME IS NULL;

//96标准--右关联
SELECT  ject.name,stud.name FROM
    stud RIGHT JOIN sj  ON stud.id=sj.studid
         RIGHT JOIN ject ON  ject.id = sj.subjectid
    WHERE stud.NAME I
S NULL;

 

※演示自动增长列与字段值唯一性约束

CREATE TABLE aa(
       id INT AUTO_INCREMENT PRIMARY KEY,
       nm VARCHAR(32) UNIQUE
);
INSERT INTO aa(nm) VALUES('uuu');

 

 

 


 

 

 

 

 

 

 

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

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

相关文章

adb连接木木模拟器

木木模拟器调试到开发模式,在一般在\Nemu\vmonitor\bin中,运行命令行adb connect 127.0.0.1:7555

玩转MySQL -----处理大数据对象

一、大数据对象简介 1.LOB(Large Object,大型对象)类型的字段现在用得越来越多了。因为这种类型的字段,容量大(最多能容纳4GB的数据),且一个表中可以有多个这种类型的字段,很灵活&am…

http 转 https 操作步骤

http 转https 花了很多的时间,走了很多的网弯路,最后还是弄好了 步骤: 第一步: 进入阿里云账号,进入 控制台 -》 安全(云盾) -》 CA证书服务 -》 购买证书 -》 注意:这里选项的时候…

python数据类型转换

Python数据类型转换 Python数据类型之间的转换 函数描述 int(x [,base]) 将x转换为一个整数 long(x [,base] ) 将x转换为一个长整数 float(x) 将x转换到一个浮点数 complex(real [,imag]) 创建一个复数 str(x) 将对象 x 转换为字符串 repr(x) 将对象 x 转换为表达式…

搭建frida+木木模拟器运行环境

目录 pip安装frida安装木木模拟器开启模拟器的root权限打开模拟器USB调试安装RE文件管理器 下载frida服务端-Android下载frida-server文件移动文件到tmp下 使用adb连接mumu模拟器设置frida-server权限并启动查看是否启动成功 使用python调用 pip安装frida 本机环境win10 (AMD6…

利用ChatGPT 5分钟制作一份思维导图

一、利用ChatGPT列出思维导图大纲 二、利用ChatGPT继续将大纲转化为markdown语法 三、将上面内容复制到txt文档中保存 四、修改文件名后缀为md 五、将生成的md文件导入到xmind中 打开xmind软件,通过「文件→导入→markdown」,选择我们刚刚创建的文件导入…

音视频技术开发周刊 | 302

每周一期,纵览音视频技术领域的干货。 新闻投稿:contributelivevideostack.com。 ChatGPT神器Code Interpreter终于开放,到底怎么用?这里有一份保姆级教程 Code Interpreter 已经正式开放。 上海世界AI大会:MidJourney…

Window之系统开机Administrator账户被停用

在我们的Win7系统开机时如果没有设置其他账户,并且我们的Administrator账户被停用怎么进入Win7系统呢? 解决方法: 重启电脑后按F8进入安全模式, 右键点击“我的电脑” -- “管理” -- “本地用户和组” -- “用户” -- 右键“Ad…

Spug“账户已被系统禁用”的解决办法

前置文章: Spug发布前端项目实战全过程https://blog.csdn.net/wdy_2099/article/details/120215392 Spug设置报警提醒功能(钉钉、微信、邮箱)落地详细https://blog.csdn.net/wdy_2099/article/details/120224867 问题:未知原因导…

桌面计算机安全禁用账户,Win10电脑提示“你的账户已被停用,请向系统管理员咨询”的解决教程...

有用户在安装 解决方法一: 1、此情况可以长按电源键强制关机再开机看到WIN10登陆界面时再次长按电源键强制关机,如此三次后再开机会看到“查看高级修复选项”的按钮,点此按钮会进入WINRE环境,选择“疑难解答”; 2、选择“高级选项”; 3、选择…

【转】您的账户已被停用,请向系统管理员咨询解决办法

升级win10后发现开机时进入安全模式长按F8已经没用了,其实win10中把安全模式放入了系统修复模块,下面就来介绍下win10如何进入安全模式。 进入下边这个界面可通过按住 SHIFT 点击重启即可 工具/原料 win10 方法/步骤 打开“开始”菜单,找到里…

您的账户已被停用,请向系统管理员咨询 解决方案(亲测有效)

当你的电脑误操作了以下步骤,或者被篡改了设置了这里 那恭喜你,重启后就登不上Administrator账户了 首先看一下网上的三种无效方式 无效方式一:安全模式进入用户和组 一般两种方式进入安全模式: 方式一:F8进入 方式二:按住shift 重启 (1)选中其中的安全模式,在安全…

国庆节文字摘抄好词好句好段怎么写?用便签记录就可以

一般来说,在国庆节有不少学生都有一项这样的作业,这就是写国庆节文字摘抄,例如一些关于国庆节的好词好句好段,这不仅可以帮助我们积累一些知识,也可以让我们在以后的日常生活、写作文中使用到。那么国庆节文字照抄怎么…

我一直都以为摘录好词好句是一个好…

我一直都以为摘录好词好句是一个好习惯,以前我看到一些好词好句我就会把它们抄写到笔记本上,把它们背熟,然后到了写文章时就滴字不漏地照搬进去。直到现在我才明白,原来这是一个坏习惯,说是摘录,其实是抄袭…

关注CSDN社区微信,更多精彩等你来

CSDN社区微信公众号“程序人生”(微信ID:coder_life)来了,每天我们会将CSDN社区中大量的优质内容浓缩成1~3篇文章,推送到您的手机中,让您无论何时何地都能感受到知识的精彩、技术的力量。 扫描二维码关注&a…

常用值得收藏的网站/软件 持续更新中

学识决定眼界,眼界决定格局,格局决定人生。 文章目录 一、查询与资源类二、教育与学习类三、代码与资源类四、办工类五、技术与知识面类六、交流与分享类七、其他 这些年经常用的网站,觉得非常实用。与大家分享分享,独乐乐不如众乐…

1.Postman之发送get请求

Postman之发送get请求 1.创建一个集合 2.在集合中创建一个请求 3.GET请求获取北京今天天气: (1)天气API接口文档:http://doc.tianqiapi.com/603579 (2)请求API接口:http://www.tianqiapi.co…

关于PostMan发送请求获得响应

关于PostMan发送请求 在PostMan里面设置引用全局变量(环境变量和集合变量不常用) 附上官网变量设置:https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/#writing-test-assertions 1、点…

post请求变成了get请求,是怎么回事?

答案:**请求协议错了 ,请检查协议。**如果心急的就不用往下看了——特指jmeter接口请求 详解: 测试中有时要把用域名访问的接口,切换为用IP访问,这时,往往请求结果会出现Java报错,而且请求中 …