1、FROM子句
SELECT的查询对象由FROM子句指定。
语法格式:FROM 表名1 [ [ AS ] 别名1] [,表名2 [ [ AS ] 别名2 ] ] | JOIN子句
FROM子句可以用两种方式引用一个表,第一种方式是使用USE语句让一个数据库成为当前数据库,在该情况下,若在FROM子句中指定表名,则该表应该属于当前数据库。第二种方式是指定的时候在表名前带上表所属数据库的名字。
例如,假设当前数据库是db1,现在要显示数据库db2里的表tb的内容,则使用语句:
SELECT * FROM db2.tb;
在SELECT关键字后指定列名的时候也可以在列名前带上所属数据库和表的名字,但是一般来说,若选择的字段在各表中是唯一的,就没有必要去特别指定。
例:从Members表中检索出所有客户的信息,并使用表别名Users
SELECT * FROM Members AS Users
2、多表连接
若要在不同表中查询数据,则必须在FROM子句中指定多个表。将不同列的数据组合到一个表中叫做表的连接。例如,在Bookstore数据库中需要查找订购了“网页程序设计”图书的会员的姓名和订购数量,就需要将Book、Members和Sell这3个表进行连接,才能找到结果
2.1、全连接
全连接是指将每个表的每行都与其他表中的每行交叉以产生所有可能的组合,列包含了所有表中出现的列,也就是笛卡尔积。例如,表1有3行,表2有2行,则他们全连接后的表3有3x2=6行。
2.2、内连接
全连接得到的表产生数量非常多的行,其得到的行数为每个表中行数之积,而且全连接产生的表中数据在大多数情况下都没有意义。在这样的情形下,通常要设定条件来将结果集减少且有意义的表,这样的连接即为内连接。若设定的条件是等值条件,也叫等值连接。
2.3、外连接
外连接包括左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)两种
左外连接:结果表中除了匹配行外,还包括左表有的但右表中不匹配的行,对于这样的行,从右表被选择的列设置为NULL。
右外连接:结果表中除了匹配行外,还包括右表有的但左表中不匹配的行,对于这样的行,从左表被选择的列设置为NULL。
若FROM子句中将各表用逗号分隔,就指定了全连接,全连接得到的表产生数量非常多的行
例:查找Bookstore数据库中客户订购的图书书名、订购册数和订购时间
SELECT Book.书名,Sell.订购册数,Sell.订购时间
FROM Book,Sell
WHERE Book.图书编号=Sell.图书编号;
3、 JOIN连接
使用JOIN关键字建立多表连接时,JOIN子句定义了如何使用JOIN关键字连接表
语法格式:
表名1 INNER JOIN 表名2
| 表名1 {LEFT | RIGHT} [ OUTER ] JOIN 表名2
ON 连接条件 | USING(列名)
指定INNER关键字的连接是内连接。内连接是在FROM子句产生的中间结果中应用ON条件后得到的结果。内连接是系统默认的,可以省略INNER关键字。使用内连接后,FROM子句中ON条件主要是用来连接表,其他并不属于连接表的条件可以使用WHERE子句来指定。
例:查找Bookstore数据库中客户订购的图书书名、订购册数和订购时间
SELECT Book.书名,Sell.订购册数,Sell.订购时间
FROM Book INNER JOIN Sell
ON(Book.图书编号=Sell.图书编号);
例:查找购买了“网页程序设计”且订购数量大于5本的图书信息
SELECT 书名,订购册数
FROM Book JOIN Sell
ON Book.图书编号=Sell.图书编号
WHERE 书名='网页程序设计' AND 订购册数>5;
例:查找购买了“网页程序设计”且订购数量大于5本的图书、会员姓名和订购册数
SELECT Book.图书编号,会员姓名,书名,订购册数
FROM Sell JOIN Book ON Book.图书编号=Sell.图书编号
JOIN Members ON Sell.身份证号=Members.身份证号
WHERE 书名='网页程序设计' AND 订购册数>5;
作为特例,可以将一个表与其自身进行连接,称为自连接。若要在一个表中查找具有相同列值的行,则可以使用自连接。使用自连接时需为表指定两个别名,且对所有列的引用均要用别名限定。
例:查找Bookstore数据库的Sell表中订单不同、图书编号相同的图书的订单号、图书编号和订购册数
SELECT a.订单号,a.图书编号,a.订购册数
FROM Sell AS a JOIN Sell AS b
ON a.图书编号=b.图书编号 AND a.订单号!=b.订单号;
若要连接的表中有列名相同,并且连接的条件就是列名相等,则ON条件也可以换成USING子句。USING(column_list)子句用于为一系列的列进行命名。这些列必须同时在两个表中存在。其中column_list为两表中相同的列名。
指定OUTER关键字的连接为外连接。
例:查找所有图书的图书编号、数量及订购了图书的会员身份证号,若从未订购过,也要包括其情况。
SELECT Book.图书编号,Book.数量,身份证号
FROM Book LEFT OUTER JOIN Sell
ON Book.图书编号=Sell.图书编号;
若不使用LEFT OUTER JOIN,则结果中不会包括未订购过的图书信息。使用了左外连接后,结果中返回的行中有未订购过的图书信息,相应行的身份证号字段值为NULL。
4、子查询
在查询条件中,可以使用另一个查询的结果作为条件的一部分。例如,判定列值是否与某个查询的结果集中的值相等,作为查询条件一部分的查询称为子查询。SQL标准允许SELECT多层嵌套使用,用来表示复杂的查询。子查询除了可以用在SELECT语句中,还可以用在INSERT、UPDATE及DELETE语句中。子查询通常与IN、EXIST谓词及比较运算符结合使用。
4.1、IN子查询
IN子查询用于进行一个给定值是否在子查询结果集中的判断。
语法格式:表达式 [ NOT ] IN (子查询)
例:查找在Bookstore数据库中张三的订单信息
思路:含有订单信息的Sell表不包含客户的姓名,只有客户的身份证号。要查找张三的订单信息,先要知道张三的身份证号。因此先要在Members表中查找张三的身份证号,再根据身份证号查询订单信息。
SELECT *
FROM Sell
WHERE 身份证号 IN
(SELECT 身份证号 FROM Members WHERE 会员姓名='张三');
4.2、比较子查询
该子查询可以认为是IN子查询的扩展,其使表达式的值与子查询的结果的结果进行比较运算
语法格式:表达式{< | <= | = | > | >= | != | <>}{ALL | SOME | ANY}(子查询)
若子查询的结果集只返回一行数据时,可以通过比较运算符直接比较。若子查询的结果集返回多行数据时,需要用{ALL | SOME | ANY}来限定
ALL指定表达式要与子查询结果集中的每个值都进行比较,当表达式的每个值都满足比较关系时,才返回true,否则返回false
SOME与ANY是同义词,表示表达式只要与子查询结果集中的某个值满足比较关系时,就返回true,否则返回false
例:查找购买了图书编号为“IS-01”的图书的会员信息
SELECT * FROM Members WHERE 身份证号=ANY
(SELECT 身份证号 FROM Sell WHERE 图书编号='IS-01');
4.3、EXISTS子查询
EXISTS谓词用于测试子查询的结果是否为空表,若子查询的结果集不为空,则EXISTS返回true,否则返回false。EXISTS还可与NOT结合使用,即NOT EXISTS,其返回值与EXISTS刚好相反。
语法格式:[ NOT ]EXISTS (子查询)
例:查找每次订购10本以上图书的会员姓名
SELECT 会员姓名 FROM Members WHERE EXISTS
(SELECT * FROM Sell WHERE 身份证号=Members.身份证号 and 订购册数>10);