谷哥的小弟学后台(04)——MySQL(4)



探索Android软键盘的疑难杂症

深入探讨Android异步精髓Handler

具体解释Android主流框架不可或缺的基石

站在源代码的肩膀上全解Scroller工作机制



Android多分辨率适配框架(1)— 核心基础

Android多分辨率适配框架(2)— 原理剖析

Android多分辨率适配框架(3)— 使用指南



自己定义View系列教程00–推翻自己和过往。重学自己定义View

自己定义View系列教程01–经常使用工具介绍

自己定义View系列教程02–onMeasure源代码详尽分析

自己定义View系列教程03–onLayout源代码详尽分析

自己定义View系列教程04–Draw源代码分析及事实上践

自己定义View系列教程05–演示样例分析

自己定义View系列教程06–具体解释View的Touch事件处理

自己定义View系列教程07–具体解释ViewGroup分发Touch事件

自己定义View系列教程08–滑动冲突的产生及其处理


版权声明


本文简单介绍

在之前的两篇博客中我们学习了MySQL的DDL、DML、DCL、DQL。

在本篇博客中,我们来一起学习:数据的完整性和多表查询


数据的完整性

数据的完整性可确保用户输入到数据库的数据是正确的。为此。须要在创建表时在表中加入约束。

数据完整性的分类

  • 行级的实体完整性
  • 列级的域完整性
  • 引用完整性

实体完整性

数据库表中的一行数据(即一条记录)表示一个实体(entity),实体完整性的作用就是标识每一行数据(即一条记录)使其不反复

确保实体完整性的三种约束:

  • 主键约束(primary key)
  • 唯一约束(unique)
  • 自己主动增长列(auto_increment)

主键约束(primary key)

在表中设置一个主键;被标识为主键的数据在表中是唯一的且其值不能为null

设置主键约束(primary key)的第一种方式:

CREATE TABLE student(
    id int primary key,
    name varchar(50)
);

在该方式中将id字段设置为主键,请參见第2行代码

设置主键约束(primary key)的另外一种方式:

CREATE TABLE student(
    id int,
    name varchar(50),
    primary key(id)
);

在该方式中,先定义了字段id,然后设置该字段为主键,请參见第4行代码。

若採用该方式很便于设置联合主键,请看例如以下演示样例:

CREATE TABLE student(
    classid int,
    studentid int,
    name varchar(50),
    primary key(classid。studentid)
);

在该演示样例中,将classid和studentid定义为联合主键,请參见第5行代码。

请注意:不要把联合主键理解成两个主键。它们是以两个字段联合的形式作为主键

设置主键约束(primary key)的第三种方式:

CREATE TABLE student(
    id int,
    name varchar(50)
);
ALTER TABLE student  ADD  PRIMARY  KEY (id);

在该演示样例中。先创建了表,然后利用ALTER语句设置id字段为主键。

唯一约束(unique)

为字段加入唯一约束(unique)后该字段相应的值不能反复。是唯一的。

请看例如以下演示样例:

CREATE TABLE student(
    id int primary key,
    name varchar(50) unique
);

在该演示样例中利用unique关键字为字段name加入唯一约束,请參见第3行代码。

自己主动增长列(auto_increment)

可用auto_increment关键字标识int类型的字段。设置后该字段的值会自己主动地增长。

常见的做法是给int类型的主键加入auto_increment。请看例如以下演示样例:

CREATE TABLE student(
    id int primary key auto_increment,
    name varchar(50)
);

在该演示样例中将主键id设置为auto_increment,那么该字段的值会自己主动地增长。

域完整性

域完整性用于确保表中单元格的数据正确;所以,域完整性就代表了表中单元格的完整性。

在之前介绍实体完整性时可知:在为字段设置主键约束(primary key)和唯一约束(unique)以及自己主动增长列(auto_increment)后,当往表中插入数据时会将该数据与该列中其它单元格的数据相比較。满足条件后才会插入到数据库。

可是域完整性的作用范围仅仅限定于本单元格,它不会将带插入数据与其它单元格相比較。

常见的域完整性约束:

  • 数据类型

    字段的数据类型本身就是一种约束。比方定义了字段id int;当往该单元格中插入varchar类型的数据,数据库就会报错。

  • 非空约束(NOT NULL)

    限定单元格的数据不能是NULL

  • 默认值约束(DEFAULT)

    为单元格设置默认值

  • check约束

    检查单元格中数据,比方check(sex=’男’ or sex=’女’)。可是。请注意MySQL并不支持check约束,而其它数据库比方Oracle是支持的。

关于数据类型和check约束。鉴于其比較简单,故在此不再赘述。以下将介绍非空约束(NOT NULL)和默认值约束(DEFAULT)。

非空约束(NOT NULL)

请看例如以下演示样例:

CREATE TABLE student(
    id int PRIMARY KEY,
    name varchar(50) NOT NULL,
    gender varchar(10)
);

在该演示样例中设定name字段为NOT NULL,所以在插入数据时必须为该字段设值。

默认值约束(DEFAULT)

请看例如以下演示样例:

CREATE TABLE student(
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL UNIQUE,
    gender VARCHAR(10) DEFAULT ‘女‘
);

在该演示样例中为gender字段设值了默认值,所以能够用例如以下方式插入数据

insert into student(id,name) values(1,‘toc‘);
insert into student(id,name,gender) values(2,‘jok‘,‘男‘);
insert into student(id,name,gender) values(3,‘jerry‘,default);

引用完整性

引用完整性也叫參照完整性。经常使用于设值外键。

请看例如以下演示样例:

CREATE TABLE student(
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    gender VARCHAR(10) DEFAULT ‘男‘
);

CREATE TABLE score(
    scoreid INT PRIMARY KEY,score
    studentid INT ,
    scoreresult INT,
    CONSTRAINT fk_score_studentid FOREIGN KEY (studentid) REFERENCES student(id)
);

INSERT INTO student(id,name,gender) VALUES(1,‘大泽玛利亚‘,DEFAULT);
INSERT INTO student(id,name,gender) VALUES(1,‘武藤兰姐姐‘,‘女‘);
INSERT INTO student(id,name,gender) VALUES(3,‘苍井空妹妹‘,‘女‘);
INSERT INTO student(id,name,gender) VALUES(4,‘波少野结衣‘,DEFAULT);

INSERT INTO score(scoreid,studentid,scoreresult) VALUES(200,1,98);
INSERT INTO score(scoreid,studentid,scoreresult) VALUES(201,2,97);
INSERT INTO score(scoreid,studentid,scoreresult) VALUES(202,3,93);
INSERT INTO score(scoreid,studentid,scoreresult) VALUES(203,3,91);
INSERT INTO score(scoreid,studentid,scoreresult) VALUES(204,4,88);
INSERT INTO score(scoreid,studentid,scoreresult) VALUES(205,4,69);

在此建立两张表。当中。学生表student作为主表,分数表score作为子表。请注意在score中的studentid学生编号表示成绩是属于哪个学生的。该值必须是student表中id列里的值。所以,利用外键FOREIGN KEY将score中的studentid与student表中id建立起联系,请參见代码第11行。

小结例如以下:

  • 子表里的外键必须是主表的主键
  • 子表里外键的数据类型必须与主表中主键的数据类型一致
  • 也可利用SQL语句设置外键,例如以下:

    ALTER TABLE score ADD CONSTRAINT fk_score_studentid FOREIGN KEY(studentid) REFERENCES student(id);


表与表之间的关系

经常使用的表与表之间的关系有一对一,一对多,多对多,现分别作例如以下介绍。

一对一

请看例如以下演示样例:

CREATE TABLE person(
    personid INT PRIMARY KEY,
    personname VARCHAR(50) NOT NULL
);

CREATE TABLE persondetail(
    detailid INT PRIMARY KEY,
    job VARCHAR(30),
    hobby VARCHAR(50),
    address VARCHAR(50)
);

ALTER TABLE persondetail ADD CONSTRAINT fk_detailid_personid FOREIGN KEY (detailid) REFERENCES person(personid);

INSERT INTO person(personid,personname) VALUES(1,‘大泽玛利亚‘);
INSERT INTO person(personid,personname) VALUES(2,‘武藤兰姐姐‘);
INSERT INTO person(personid,personname) VALUES(3,‘苍井空妹妹‘);
INSERT INTO person(personid,personname) VALUES(4,‘波少野结衣‘);

INSERT INTO persondetail(detailid,job,hobby,address) VALUES(1,‘演员‘,‘看书‘,‘东京‘);
INSERT INTO persondetail(detailid,job,hobby,address) VALUES(2,‘诗人‘,‘弹琴‘,‘大阪‘);
INSERT INTO persondetail(detailid,job,hobby,address) VALUES(3,‘作家‘,‘摄影‘,‘千叶‘);
INSERT INTO persondetail(detailid,job,hobby,address) VALUES(4,‘模特‘,‘练字‘,‘仙台‘);

在该演示样例中存在两张表person和persondetail。

person表中的每一个人、persondetail中的每条具体信息,这两者一一相应。请參见代码第13行

一对多

请看例如以下演示样例:

CREATE TABLE student(
    studentid INT PRIMARY KEY,
    studentname VARCHAR(50) NOT NULL
);

CREATE TABLE report(
    scoreid INT PRIMARY KEY,
    studentid INT,
    score INT
);

ALTER TABLE report ADD CONSTRAINT fk_report_student FOREIGN KEY (studentid) REFERENCES student(studentid);

INSERT INTO student(studentid,studentname) VALUES(1,‘大泽玛利亚‘);
INSERT INTO student(studentid,studentname) VALUES(2,‘武藤兰姐姐‘);
INSERT INTO student(studentid,studentname) VALUES(3,‘苍井空妹妹‘);
INSERT INTO student(studentid,studentname) VALUES(4,‘波少野结衣‘);

INSERT INTO report(scoreid,studentid,score) VALUES(1,1,87);
INSERT INTO report(scoreid,studentid,score) VALUES(2,1,77);
INSERT INTO report(scoreid,studentid,score) VALUES(3,2,67);
INSERT INTO report(scoreid,studentid,score) VALUES(4,2,77);
INSERT INTO report(scoreid,studentid,score) VALUES(5,3,87);
INSERT INTO report(scoreid,studentid,score) VALUES(6,4,77);

在该演示样例中存在两张表:学生表student和成绩表report。

每一个学生相应多门课程的成绩,这就是一对多的关系;请參见代码第13行

多对多

请看例如以下演示样例:

CREATE TABLE student(
    studentid INT PRIMARY KEY,
    studentname VARCHAR(50) NOT NULL
);

CREATE TABLE teacher(
    teacherid INT PRIMARY KEY,
    teachername VARCHAR(50) NOT NULL
);

CREATE TABLE student_teacher_relation(
    sid INT,
    tid INT
);

ALTER TABLE student_teacher_relation ADD CONSTRAINT fk_sid FOREIGN KEY (sid) REFERENCES student(studentid);
ALTER TABLE student_teacher_relation ADD CONSTRAINT fk_tid FOREIGN KEY (tid) REFERENCES teacher(teacherid);

INSERT INTO student(studentid,studentname) VALUES(1,‘大泽玛利亚‘);
INSERT INTO student(studentid,studentname) VALUES(2,‘武藤兰姐姐‘);
INSERT INTO student(studentid,studentname) VALUES(3,‘苍井空妹妹‘);
INSERT INTO student(studentid,studentname) VALUES(4,‘波少野结衣‘);

INSERT INTO teacher(teacherid,teachername) VALUES(1,‘田中瑞稀‘);
INSERT INTO teacher(teacherid,teachername) VALUES(2,‘奧村麻依‘);
INSERT INTO teacher(teacherid,teachername) VALUES(3,‘大竹里步‘);
INSERT INTO teacher(teacherid,teachername) VALUES(4,‘田中瑞稀‘);

INSERT INTO student_teacher_relation(sid,tid) VALUES(1,1);
INSERT INTO student_teacher_relation(sid,tid) VALUES(1,3);
INSERT INTO student_teacher_relation(sid,tid) VALUES(2,1);
INSERT INTO student_teacher_relation(sid,tid) VALUES(2,2);
INSERT INTO student_teacher_relation(sid,tid) VALUES(2,3);
INSERT INTO student_teacher_relation(sid,tid) VALUES(3,4);
INSERT INTO student_teacher_relation(sid,tid) VALUES(4,1);

在该演示样例中存在三张表:student、teacher、student_teacher_relation。每一个学生可能上几个老师的课。每一个老师可能教多个学生,这就是多对多的关系,故在此创建了student_teacher_relation表;请參见代码第20-21行

关于这三张表的关系请參见下图:

原本student和teacher是多对多的关系,为化解该关系引入了student_teacher_relation表;如今转换成了student与student_teacher_relation的一对多以及teacher与student_teacher_relation的一对多。


多表查询

如今開始进入有些繁琐,可是又很重要的MySQ多表查询。

合并结果集

合并结果集就是把两个select语句的查询结果合并到一起。即:

SELECT * FROM table1 关键字 SELECT * FROM table2

合并结果集的小结:

  • 被合并的两个结果它们的列数、列类型必须同样!
  • 使用UNION关键字去除结果集中的反复记录
  • 使用UNION ALL关键字则不会去除结果集中的反复记录

请看例如以下演示样例:

CREATE TABLE student(
    studentid INT PRIMARY KEY,
    studentname VARCHAR(50) NOT NULL,
    studentaddress VARCHAR(50) DEFAULT ‘东京‘
);

CREATE TABLE person(
    personid INT PRIMARY KEY,
    personname VARCHAR(50) NOT NULL,
    age INT DEFAULT 18,
    personaddress VARCHAR(50) DEFAULT ‘大阪‘
);

INSERT INTO student(studentid,studentname) VALUES(1,‘大泽玛利亚‘);
INSERT INTO student(studentid,studentname) VALUES(2,‘武藤兰姐姐‘);
INSERT INTO student(studentid,studentname) VALUES(3,‘苍井空妹妹‘);
INSERT INTO student(studentid,studentname) VALUES(4,‘波少野结衣‘);

INSERT INTO person(personid,personname) VALUES(1,‘田中瑞稀‘);
INSERT INTO person(personid,personname) VALUES(2,‘奧村麻依‘);
INSERT INTO person(personid,personname) VALUES(3,‘大竹里步‘);
INSERT INTO person(personid,personname) VALUES(4,‘波少野结衣‘);

SELECT studentid AS id,studentname AS name FROM student UNION ALL SELECT personid,personname FROM person;

连接查询

连接查询就是求出多个表的乘积。

比方:table1连接table2。那么查询出的结果就是table1*table2。

可是请注意:连接查询会产生笛卡尔积,比方:集合A={a,b},集合B={0,1,2}。则集合A和B的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。这当然不是我们想要的结果。那么怎么去除反复的记录和不须要的记录呢?可通过表之间都存在关联关系(比方外键)去除笛卡尔积。

请看例如以下演示样例:

CREATE TABLE student(
    studentid INT PRIMARY KEY,
    studentname VARCHAR(50) NOT NULL
);

CREATE TABLE report(
    scoreid INT PRIMARY KEY,
    studentid INT,
    score INT
);

ALTER TABLE report ADD CONSTRAINT fk_report_student FOREIGN KEY (studentid) REFERENCES student(studentid);

INSERT INTO student(studentid,studentname) VALUES(1,‘大泽玛利亚‘);
INSERT INTO student(studentid,studentname) VALUES(2,‘武藤兰姐姐‘);
INSERT INTO student(studentid,studentname) VALUES(3,‘苍井空妹妹‘);
INSERT INTO student(studentid,studentname) VALUES(4,‘波少野结衣‘);

INSERT INTO report(scoreid,studentid,score) VALUES(1,1,87);
INSERT INTO report(scoreid,studentid,score) VALUES(2,1,77);
INSERT INTO report(scoreid,studentid,score) VALUES(3,2,67);
INSERT INTO report(scoreid,studentid,score) VALUES(4,2,77);
INSERT INTO report(scoreid,studentid,score) VALUES(5,3,87);
INSERT INTO report(scoreid,studentid,score) VALUES(6,4,77);

如今须要查询出每一个学生每门课的成绩,能够这么做:

SELECT * FROM student,report WHERE student.studentid=report.studentid;

这么查询出来发现结果集中有两个studentid,这显然不够直观和美观。所以我们能够在查询时筛选出须要的数据:

SELECT student.studentid,student.studentname,report.scoreid,report.score
FROM student,report
WHERE student.studentid=report.studentid;

在此。筛选出studentid、studentname、scoreid、score就可以。这么做目的是达到了,可是认为SQL语句很长有些臃肿;嗯哼。我们能够给表取列名来解决这个小问题:

SELECT s.studentid,s.studentname,r.scoreid,r.score
FROM student s,report r
WHERE s.studentid=r.studentid;

在此给student表取别名为s,report表取别名为r,再运行查询就可以。

当然,还能够继续在WHERE中加入查询条件,比方:

SELECT s.studentid,s.studentname,r.scoreid,r.score
FROM student s,report r
WHERE s.studentid=r.studentid AND r.score>70;

内连接查询

在刚才连接查询的演示样例中使用的SQL语句不是标准的查询方式。

为了规范和标准。在该情况下建议使用:

SELECT…FROM table1 INNER JOIN table2 ON…WHERE…;

这样的查询方式也称为内连接查询

请看例如以下演示样例:

SELECT s.studentid,s.studentname,r.scoreid,r.score
FROM student s INNER JOIN report r
ON s.studentid=r.studentid WHERE r.score>70;

内连接小结:

  • MySQL默认的连接方式就是内连接
  • INNER JOIN可简写为JOIN
  • ON专门用于主键和外键的匹配

外连接查询

外链接查询分为:左外连接查询和右外链接查询

先来看左外连接查询。

左外连接查询经常使用语句例如以下所看到的:

SELECT… FROM table1 LEFT OUTER JOIN table2 ON…;

请看例如以下演示样例:

CREATE TABLE student(
    studentid INT PRIMARY KEY,
    studentname VARCHAR(50) NOT NULL
);

CREATE TABLE report(
    scoreid INT PRIMARY KEY,
    studentid INT,
    score INT
);

ALTER TABLE report ADD CONSTRAINT fk_report_student FOREIGN KEY (studentid) REFERENCES student(studentid);

INSERT INTO student(studentid,studentname) VALUES(1,‘大泽玛利亚‘);
INSERT INTO student(studentid,studentname) VALUES(2,‘武藤兰姐姐‘);
INSERT INTO student(studentid,studentname) VALUES(3,‘苍井空妹妹‘);
INSERT INTO student(studentid,studentname) VALUES(4,‘波少野结衣‘);

INSERT INTO report(scoreid,studentid,score) VALUES(1,1,87);
INSERT INTO report(scoreid,studentid,score) VALUES(2,1,77);
INSERT INTO report(scoreid,studentid,score) VALUES(3,2,67);
INSERT INTO report(scoreid,studentid,score) VALUES(4,2,77);
INSERT INTO report(scoreid,studentid,score) VALUES(5,3,87);

在此建立两张表并向表中插入数据。

先来看学生表。一共四个学生,studentid值从1到4。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGZkZmhs/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="这里写图片描写叙述" title="">

再来看成绩表

请注意,studentid为4,studentname为波少野结衣的同学并没有參加考试。所以与她相关的信息没有出如今这张表中。

如今我们使用左外连接查询学生成绩:

SELECT *
FROM student s LEFT OUTER JOIN report r
ON s.studentid=r.studentid;

查询结果例如以下所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGZkZmhs/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="这里写图片描写叙述" title="">

呃….这里的数据比較冗余。我们换种方式筛选出最实用的信息:

SELECT s.studentid,s.studentname,r.scoreid,r.score
FROM student s LEFT OUTER JOIN report r
ON s.studentid=r.studentid;

查询结果例如以下所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGZkZmhs/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="这里写图片描写叙述" title="">

嗯哼,数据清晰多了。

请注意:studentid为4,studentname为波少野结衣的同学并没有參加考试,可是她依旧出如今了该结果集中。

这是为什么呢?

事实上,这正是左外连接查询的特点:

  • 左外连接參照的是LEFT OUTER左边的表,即此处的student表
  • 首先查出满足ON条件语句的数据
  • 再查出不满足ON条件但存在于左表的数据。仅仅只是其相应值为NULL
  • 可省略OUTER关键字

对比刚才的演示样例。可知:先查出了两张表中满足studentid=studentid的数据,然后再加入了student表中不满足studentid=studentid的数据,比方此处波少野结衣,它根本就不在report表中,所以在该结果集中她所相应的scoreid和score的值为NULL。

当然。我们能够继续使用where语句作进一步的筛选。比如:

SELECT s.studentid,s.studentname,r.scoreid,r.score
FROM student s LEFT OUTER JOIN report r
ON s.studentid=r.studentid WHERE score>80;

查询结果例如以下所看到的:

再来看右外连接查询。

右外连接查询经常使用语句例如以下所看到的:

SELECT… FROM table1 RIGHT OUTER JOIN table2 ON…;

它和左外连接查询很相似。在此,不再赘述。

比方刚才的左外连接查询语句能够换成这样:

SELECT s.studentid,s.studentname,r.scoreid,r.score
FROM report r RIGHT OUTER JOIN student s
ON s.studentid=r.studentid;

查询出来的结果是一样的。

自然连接查询

在介绍连接查询时。我们知道使用连接查询会产生笛卡尔积。在该积中存在许多没用的数据;此时,我们通常使用主外键之间的等式来剔除它们。假若使用自然连接,那么程序会自己主动帮我们找到主外键之间的等式。

自然连接查询经常使用语句例如以下所看到的:

SELECT …. FROM table1 NATURAL JOIN table2;

请看例如以下演示样例:

CREATE TABLE student(
    studentid INT PRIMARY KEY,
    studentname VARCHAR(50) NOT NULL
);

CREATE TABLE report(
    scoreid INT PRIMARY KEY,
    studentid INT,
    score INT
);

ALTER TABLE report ADD CONSTRAINT fk_report_student FOREIGN KEY (studentid) REFERENCES student(studentid);

INSERT INTO student(studentid,studentname) VALUES(1,‘大泽玛利亚‘);
INSERT INTO student(studentid,studentname) VALUES(2,‘武藤兰姐姐‘);
INSERT INTO student(studentid,studentname) VALUES(3,‘苍井空妹妹‘);
INSERT INTO student(studentid,studentname) VALUES(4,‘波少野结衣‘);

INSERT INTO report(scoreid,studentid,score) VALUES(1,1,87);
INSERT INTO report(scoreid,studentid,score) VALUES(2,1,77);
INSERT INTO report(scoreid,studentid,score) VALUES(3,2,67);
INSERT INTO report(scoreid,studentid,score) VALUES(4,2,77);
INSERT INTO report(scoreid,studentid,score) VALUES(5,3,87);
INSERT INTO report(scoreid,studentid,score) VALUES(6,4,99);

在此,准备两张表,再向表中插入数据,如今使用自然连接查询:

SELECT * FROM student NATURAL JOIN report;

结果例如以下图所看到的:

嗯哼,看到吧。它的效果和内连接是一样的。

那么自然连接就能够全然代替内连接么?非也!使用自然连接有一个很重要的前提条件:须要两张表中有一列(一般是主表的主键和子表的外键)的名称和类型全然一致!比方。该演示样例中student表中的studentid和report表中的studentid。

子查询

子查询就是嵌套查询。即SELECT中包括了另外一个SELECT。

我们先准备一些数据

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
) ;

CREATE TABLE dept(
    deptno  INT,
    dname   VARCHAR(14),
    loc     VARCHAR(13)
);

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);

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 deptno = (SELECT deptno FROM emp WHERE ename=‘SCOTT‘);

查询工资高于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);

查询员工编号为7788的员工名称、员工工资、部门名称、部门地址

SELECT e.ename, e.sal, d.dname, d.loc
FROM emp e, (SELECT dname,loc,deptno FROM dept) d
WHERE e.deptno=d.deptno AND e.empno=7788;

当然。也能够不用子查询。方式例如以下:

SELECT e.ename,e.sal,d.dname,d.loc
FROM emp e,dept d
WHERE e.deptno=d.deptno
AND e.empno=7788;

自连接

通俗地讲:自连接就是一张表与其本身连接

请看例如以下演示样例:

请查询员工编号为7369的员工姓名及其经理编号和经理姓名

SELECT e1.empno,e1.ename,e2.mgr,e2.ename
FROM emp e1, emp e2
WHERE e1.mgr = e2.empno AND e1.empno = 7369;

在数据库的表中。员工姓名,员工编号。经理姓名,经理编号在同一张表中。

所以,在此将empno表与自己相连接后再查询;相当于用自身虚拟出另外一张一模一样的表,然后进行连接查询。

时间: 2024-11-05 18:32:25

谷哥的小弟学后台(04)——MySQL(4)的相关文章

谷哥的小弟学后台(01)——MySQL(1)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Android多分辨率适配框架(3)- 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View

谷哥的小弟学后台(02)——MySQL(2)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Android多分辨率适配框架(3)- 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View

谷哥的小弟学后台(06)——JDBC

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Android多分辨率适配框架(3)- 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View

谷哥的小弟学前端(07)——CSS基础知识(5)

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Android多分辨率适配框架(3)- 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View

寒哥教你学iOS - 经验漫谈

http://www.jianshu.com/p/cb54054d3add 寒哥教你学iOS - 经验漫谈 字数2848 阅读1896 评论19 喜欢43 顺便来个广告 iOS开发者 群173499350 给大家提供一个交流技术 也可以聊天打屁的平台 本篇文章主要讲解 4个问题 load妙用 aop面向切面编程 NSNumber Or Int @()适配64位 1 让appDelegate 减少负担 经过漫长时间的学习 你终于掌握了iOS大法 你找到了份iOS开发的工作 信誓旦旦的要开始你的co

1097:零起点学算法04——再模仿一个算术题

1097: 零起点学算法04--再模仿一个算术题 Time Limit: 1 Sec  Memory Limit: 128 MB   64bit IO Format: %lldSubmitted: 2627  Accepted: 2202[Submit][Status][Web Board] Description 上题会模仿了吧.再来模仿一个. 现在要求你模仿一个乘法的算术题 Input 没有输入 Output 输出9乘以10的值 Sample Output 90 Source 零起点学算法

【凯子哥带你学Android】Andriod性能优化之列表卡顿——以“简书”APP为例

这几天闲得无聊,就打开手机上的开发者模式里面的"GPU过度绘制"功能,看看别家的App做的咋样,然后很偶然的打开了"简书",然后就被它的过度绘制惊呆了,于是写了这篇性能分析的文章,从一个只有APK文件的角度,说下如何寻找布局中可能存在的性能问题,以及解决方案.本文章以简书Android最新版本1.9.1进行分析. GPU过度绘制 Hierarchy View SysTrace TraceView 总结 分析资源下载 GPU过度绘制 首先打开下面两个功能开关 开发者模

马哥学习笔记二十六——MySQL主从复制

配置MySQL复制基本步骤: 一.master 1.启用二进制日志 log-bin = master-bin log-bin-index = master-bin.index 2.选择一个惟一server-id server-id = {0-2^32} 3.创建具有复制权限的用户 REPLICATION SLAVE REPLICATION CLIENT 二.slave 1.启用中继日志 relay-log = relay-log relay-log-index = 2.选择一个惟一的server

【马哥linux学员学习笔记】MySQL多实例详解

本文作者系马哥linux学员云中鹤. 目录 一.基本概念 1.MySQL多实例 就是在一台机器上面开启多个不同的端口,运行多个MySQL服务进程.这些MySQL多实例公用一套安装程序,使用不同的(也可以是相同的)配置文件,启动程序,数据文件.在提供服务时候,多实例MySQL在逻辑上看来是各自独立的,多个实例的自身是根据配置文件对应的设定值,来取得相关硬件资源的多少. 2.应用场景 1).采用了数据伪分布式架构的原因,而项目启动初期又不一定有那多的用户量,为此先一组物理数据库服务器,但部署多个实例