探索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表与自己相连接后再查询;相当于用自身虚拟出另外一张一模一样的表,然后进行连接查询。

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

  1. 谷哥的小弟学前端(11)——JavaScript基础知识(2)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 具体解释Android主流框架不可或缺的基石 站在源代码的肩膀上全解Scroller工作机制 Android多分辨率适 ...

  2. 谷哥的小弟学前端(10)——JavaScript基础知识(1)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 具体解释Android主流框架不可或缺的基石 站在源代码的肩膀上全解Scroller工作机制 Android多分辨率适 ...

  3. 谷哥的小弟学前端(02)——HTML常用标签(2)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架 ...

  4. 谷哥的小弟学前端(01)——HTML常用标签(1)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架 ...

  5. 【凯子哥带你学Framework】Activity界面显示全解析(下)

    咱们接着上篇继续讲,上篇没看的请戳:[凯子哥带你学Framework]Activity界面显示全解析(上) 如何验证上一个问题 首先,说明一下运行条件: //主题 name="AppThem ...

  6. Node后台使用mysql并开启事务

    如题:node后台使用mysql数据库,并使用事务来管理数据库操作. 这里主要讲一个事务的封装并写了一个INSERT 插入操作. code: 基础code: db.config.js const my ...

  7. 寒哥教你学iOS - 经验漫谈

    http://www.jianshu.com/p/cb54054d3add 寒哥教你学iOS - 经验漫谈 字数2848 阅读1896 评论19 喜欢43 顺便来个广告 iOS开发者 群1734993 ...

  8. 寒哥教你学 iOS - 经验漫谈(转)

    转自http://www.cocoachina.com/ios/20150907/13339.html 本篇文章主要讲解 4个问题 load妙用 aop面向切面编程 NSNumber Or Int @ ...

  9. 【凯子哥带你学Framework】Activity界面显示全解析

    前几天凯子哥写的Framework层的解析文章<Activity启动过程全解析>,反响还不错,这说明“写让大家都能看懂的Framework解析文章”的思想是基本正确的. 我个人觉得,深入分 ...

随机推荐

  1. java中异常和集合

    1. java中处理错误情况有两种,1  Error,2  Exception error是无法处理的,Exception是可以处理的情况. Exception中又有两种情况,RuntimeExcep ...

  2. Jeecg 如何执行批量insert或者update操作,高效率

    方法:org.jeecgframework.core.common.dao.jdbc.SimpleJdbcTemplate.batchUpdate     原理: 基于springjdbc封装,批量提 ...

  3. Linux 使用YUM安装mysql

    yum -y install mysql-server ,系统自动下载和安装Mysql的,chkconfig --add mysqld 在服务清单中添加mysql服务service mysqld st ...

  4. Android开发12——Andorid中操作数据库的insert的两种方法以及nullColumnHack

    一.发现问题 先看两种方法插入数据 public void save(Person p){ SQLiteDatabase db = dbHelper.getWritableDatabase(); db ...

  5. java中代理,静态代理,动态代理以及spring aop代理方式,实现原理统一汇总

    若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. ...

  6. ASP.NET MVC 操作AD 获取域服务器当前用户姓名和OU信息

    #region 根据当前登录域账号 获取AD用户姓名和所在OU目录 /// <summary> /// 根据当前登录域账号 获取AD用户姓名和所在OU目录 /// </summary ...

  7. UnityTestTools測试工具

    由于工作关系,要了解Unity上的測试工具,该工具基于Nunit框架.通过查阅资料了解到在Unity5.3中做出了一些改变,自带的仅仅剩下单元測试工具,假设想用其它的工具比方断言.集成測试,就须要前往 ...

  8. CentOS7添加logstash5启动脚本

    默认情况使用rpm包安装完logstash之后没有启动脚本,这一点我觉得算是开发不够彻底.官网给了一个脚本,需要根据不同的系统版本生成对应的启动脚本,而且官网没有给明使用方法,对于新用户来说算是个坑, ...

  9. python2安装pymongo

    wget --no-check-certificate https://pypi.python.org/packages/source/p/pymongo/pymongo-2.6.3.tar.gz#m ...

  10. 刷新页面要通过F5

    而不是选中地址栏再按enter键,这样可能产生两种问题: 1.地址栏中的URL可能包括你上次提交的参数,你按了enter之后可能导致上次提交的参数重复提交 2.可能导致根本就没有刷新页面,刚才我修改了 ...