探索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. ubuntu16.4安装中文输入法

    ibus输入法 Chinese语言包安装 首先需要给Ubuntu16.04安装Chinese语言包支持.  如上图点击其中的Install/Remove Languages…,这个对话框是通过syst ...

  2. ActiveMQ + NodeJS + Stomp 入门

    NodeJS + stomp-client 入门 准备 下载ActiveMQ并安装 执行bin\win32\activemq.bat启动MQ服务 打开http://localhost:8161/adm ...

  3. verilog中的default应该赋什么样的值

    Q:在状态机的case语句中,最后要加上默认项default,可是我看到有的书上写的是一个确定的状态,有的则是不定态xxx,到底应该写那个啊?求助! A1:取决于case条件是否完备啦如果你的case ...

  4. Synplify9.6.2破解(转帖)

    Synplify9.6.2破解(转帖)   转载自:http://www.cnblogs.com/mark-sun/archive/2012/02/26/2368773.html Abstract本文 ...

  5. linux命令(28):Linux下SCP无需输入密码传输文件,python 中scp文件

    python 中scp文件:(如果下面的发送免密码已经完成的话,就直接能用下面这个) os.system('scp "%s" "%s:%s"' % (" ...

  6. windows 简单api应用

    //调用系统函数 将鼠标移动到相应位置 [DllImport("user32.dll", EntryPoint = "SetCursorPos")] publi ...

  7. contextmenu="supermenu" 属性的应用 右键菜单打开和保存功能

    <div ng-class="{'chat-dialog-news-mine':{{item.isOwn}},'chat-dialog-news-other':{{!item.isOw ...

  8. 3DES加密算法32个字节

    简介 最近开发的一个项目,使用到了3DES加密算法,加密socket服务端和客户端通信的报文,因为加密秘钥是32个字节,结果折腾了一番,现在记录下来分享! 1.Des3EncryptUtils.jav ...

  9. 10分钟-jQuery过滤选择器

    1.:first过滤选择器 本次我们介绍过滤选择器,该类型的选择器是依据某过滤规则进行元素的匹配.书写时以":"号开头,通经常使用于查找集合元素中的某一位置的单个元素. 在jQue ...

  10. Redis简述

    Redis 简单介绍 Redis 是全然开源免费的.遵守BSD协议,是一个高性能的key-value数据库. Redis 与其它 key - value 缓存产品有下面三个特点: Redis支持数据的 ...