Java EE之旅10-数据库基础(4)

为什么要进行拆表

比如说一张学生表,里面有一个字段为分数:

image.png

我们知道,一个学生可以考多门课程,有多门课程的分数,那么这时候就需要添加多个重复的数据了;而且这里并不能区分是什么课程。那么这时候就需要进行表拆分了:

image.png

进行表拆分的优点是:

  1. 实现项目的具体需求
  2. 避免大量冗余数据,提高数据的查询效率。

注意:表并不是拆分得越仔细越好,否则工作量会增加

多表查询

既然有了表拆分,那么就会有多表查询。多表查询有如下几种:

  1. 合并结果集;UNION 、 UNION ALL
  2. 连接查询
    内连接 [INNER] JOIN ON
    外连接 OUTER JOIN ON
    左外连接 LEFT [OUTER] JOIN
    右外连接 RIGHT [OUTER] JOIN
    全外连接(MySQL不支持)FULL JOIN
    自然连接 NATURAL JOIN
  3. 子查询
  4. 自连接

1 合并结果集

  1. 作用:合并结果集就是把两个select语句的查询结果合并到一起!
  2. 合并结果集有两种方式:
    UNION:去除重复记录,例如:SELECT * FROM t1 UNION SELECT * FROM t2;
    UNION ALL:不去除重复记录,例如:SELECT * FROM t1 UNION ALL SELECT * FROM t2。
  3. 要求:被合并的两个结果:列数、列类型必须相同(不相同的时候,通过SELECT关键字去筛选需要的列)。

相关的图例如下:

image.png

例子:

create table a(
    id int,
    name varchar(10),
    score int
);

create table b(
    name varchar(10),
    score int
);

insert into a values(1,'a',10),(2,'b',20),(3,'c',30);
insert into b values('a',10),('b',20),('d',40);

去除重复记录
select name,score from a union select * from b;

不去除重复记录
select name,score from a union all select * from b;

2 连接查询(重点)

连接不限于两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。直接查询多张表会产生笛卡尔积,通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除,这时候就需要N-1个查询条件。

两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个主外键关系,所以在大家不是很熟悉连接查询时,首先要学会去除无用笛卡尔积,那么就是用主外键关系作为条件来处理。如果两张表的查询,那么至少有一个主外键条件,三张表连接至少有两个主外键条件。


下面将以两个表为例进行讲解:

CREATE TABLE student(
    sid INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    sex VARCHAR(10) DEFAULT '男'
);

CREATE TABLE score(
    id INT,
    score INT,
    sid INT , -- 外键列的数据类型一定要与主键的类型一致
    CONSTRAINT fk_score_sid FOREIGN KEY (sid) REFERENCES student(id)
);

2.1 内连接查询

-- 我们通常写的连接查询又叫做99查询法,核心思想就是主外键的连接:
select s.sid,s.name,c.score from student s , score c where s.sid=c.sid;

-- 也可以写成标准的内连接查询(核心就是inner join on关键字)
select s.sid,s.name,c.score from student s inner join score c on s.sid=c.sid;

注意:内连接查询中,inner可以省略

2.2 外连接查询

外连接查询分为左、右外连接查询:

-- 左外连接查询(参照student表,student有的,即使score中对应数据为NULL,也会查询得到)
select s.sid,s.name,c.score from student s left outter join score c on s.sid=c.sid;

-- 右外连接查询(参照score表)
select s.sid,s.name,c.score from student s right outter join score c on s.sid=c.sid;

注意:左右外连接查询中,outter可以省略,其中MySQL不支持全外连接查询。

2.3 自然连接查询

大家也都知道,连接查询会产生无用笛卡尔积,我们通常使用主外键关系等式来去除它。而自然连接无需你去给出主外键等式,它会自动找到这一等式,其实就是相当于内连接查询。例如:

select * from student natural join score;

3 子查询

子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。

子查询出现的位置:

where后,作为条为被查询的一条件的一部分;
from后,作表;

当子查询出现在where后作为条件时,还可以使用如下关键字(用得比较少):
any
all

子查询结果集的形式:

单行单列(用于条件)
单行多列(用于条件)
多行单列(用于条件)
多行多列(用于表)

例子,我们还是以这个数据作为例子:

员工表emp:

    create table emp(
        empno    int,
        ename    varchar(50),
        job      varchar(50),
        mgr      int,
        hiredate date,
        sal      decimal(7,2),
        comm     decimal(7,2),
        deptno   int
    ); 
    insert into emp values(7369,'smith','clerk',7902,'1980-12-17',800,null,20);
    insert into emp values(7499,'allen','salesman',7698,'1981-02-20',1600,300,30);
    insert into emp values(7521,'ward','salesman',7698,'1981-02-22',1250,500,30);
    insert into emp values(7566,'jones','manager',7839,'1981-04-02',2975,null,20);
    insert into emp values(7654,'martin','salesman',7698,'1981-09-28',1250,1400,30);
    insert into emp values(7698,'blake','manager',7839,'1981-05-01',2850,null,30);
    insert into emp values(7782,'clark','manager',7839,'1981-06-09',2450,null,10);
    insert into emp values(7788,'scott','analyst',7566,'1987-04-19',3000,null,20);
    insert into emp values(7839,'king','president',null,'1981-11-17',5000,null,10);
    insert into emp values(7844,'turner','salesman',7698,'1981-09-08',1500,0,30);
    insert into emp values(7876,'adams','clerk',7788,'1987-05-23',1100,null,20);
    insert into emp values(7900,'james','clerk',7698,'1981-12-03',950,null,30);
    insert into emp values(7902,'ford','analyst',7566,'1981-12-03',3000,null,20);
    insert into emp values(7934,'miller','clerk',7782,'1982-01-23',1300,null,10);
    
部门表dept:

    create table dept(
        deptno    int,
        dname     varchar(14),
        loc       varchar(13)
    );
    insert into dept values(10, 'ACCOUNTING', 'NEW YORK');
    insert into dept values(20, 'RESEARCH', 'DALLAS');
    insert into dept values(30, 'SALES', 'CHICAGO');
    insert into dept values(40, 'OPERATIONS', 'BOSTON');


-- 查询工资高于scott的员工信息
SELECT * FROM emp WHERE sal>(SELECT sal FROM emp WHERE ename='scott');

-- 工资高于30号部门所有人的员工信息
SELECT * FROM emp WHERE sal>(SELECT MAX(sal) FROM emp WHERE deptno=30);

-- 查询工作和工资与scott完全相同的员工信息
SELECT * FROM emp WHERE (job,sal) IN (SELECT job,sal FROM emp WHERE ename='scott')

-- 有2个以上直接下属的员工信息
SELECT * FROM emp WHERE empno IN(SELECT mgr FROM emp GROUP BY mgr HAVING COUNT(mgr)>=2);

4 自连接查询


自连接查询的核心是把自己看成两张表。

-- 求7369员工编号、姓名、经理编号和经理姓名
SELECT e1.empno , e1.ename,e2.mgr,e2.ename 
        FROM emp e1, emp e2 
        WHERE e1.mgr = e2.empno AND e1.empno = 7369;


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • 注:1.mysql是一种关系型数据库 2.大小写不敏感 3.字符串用单引号,若字符串里有单引号,则...
    孙浩j阅读 1,284评论 0 2
  • 关系型数据库和SQL SQL语言的三个部分DML:Data Manipulation Language,数据操纵语...
    Awey阅读 1,937评论 0 13
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 亲爱的天父: 我要祝福我的孩子有理财的智慧。祢必赐福她成为财富的管理者,而不是守财奴,也不被金钱捆绑。我祝福她如同...
    青青田园阅读 947评论 0 1
  • 哪一阵秋风 吹开白云的衣角 晴空下的行人 说着秋日胜却春朝 什么暗香浮动月黄昏 我只看到 梢头的月亮将要吃饱 圆鼓...
    少水阅读 175评论 0 3