3.使用子查询访问和修改数据
子查询和连接查询1样提供了使用单个查询访问多个表中的数据的方法。子查询在其他结果的基础上提供1种有效地方式来表示WHERE子句的条件。子查询是1个SELECT语句,它定义在SELECT、INSERT、UPDATE或DELECT语句或另外一个子查询中。子查询的SELECT语句可与外部查询指向不同的表。
嵌套的子查询或嵌套的SELECT语句是指包括1个或多个子查询的SELECT语句。子查询可嵌套在外部的SELECT、INSERT、UPDATE或DELECT语句的WHERE或HAVING子句或其他子查询内。如果嵌套了多层,则总是首先评估最内层的查询。子查询同样成为内查询,也能够嵌套任意数量的子查询。任何可使用表达式的地方都可使用子查询,只要它返回的是单个值。
3.1返回多行的子查询
子查询是在SELECT语句中的WHERE子句实现的,可以把WHERE子句中的子查询分成两类:返回多行的子查询和只返回1个值的子查询。
3.1.1使用IN关键字
可使用IN关键字来判断1个表中指定列的值是不是包括在已定义的列表中,或在另外一个表中。在前1种情况下,可以指定列名、IN关键字和用来指定列进行比较的值列表;在后1种情况下,可以指定列名、IN关键字和援用另外1个表的子查询。
举例来讲,从数据库”销售管理系统“中,查询(没有)接待过顾客的业务员的相干信息。
SELECT 业务员姓名,家庭住址,电话
FROM 业务员信息
WHERE 业务员编号 (NOT)IN
( SELECT 所属业务员编号
FROM 客户信息 )
3.1.2使用EXISTS关键字
在1些情况下,只需要返回1个真值或假值。EXISTS关键字只重视子查询是不是返回行。如果子查询返回1个或多个行,那末EXISTS便返回为真,否则为假。子查询必须是1个真实的值,它用来比较不同表中两列的值。
使用EXISTS关键字引入1个子查询时,就相当于进行1次是不是存在的测试。它的作用是在WHERE子句中测试子查询返回的行是不是存在。EXISITS子查询实际上不产生任何数据,它只返回TRUE或FALSE。
举例来讲,在数据库”销售管理系统“中,查询”供应商信息“表中,”供应商编号“为1006的供应商所提供的商品的相干信息。
SELECT 商品名称,产地,单价
FROM 商品信息
WHERE EXISITS
(SELECT *
FROM 供应商信息
WHERE 供应商编号=商品信息.供应商编号
AND 供应商编号=1006)
NOT EXISTS和EXISTS相反,如果子查询没有返回行,则满足NOT EXISTS中的WHERE子句,即在子查询返回行时,NOT EXISTS查询成功。
举例来讲,在”珠宝销售系统“中,查询在”销售信息“中没有提供珠宝并且其所在城市不是北京市的珠宝商的相干信息,并按”珠宝商所在城市“进行排序。
SELECT 珠宝商姓名,珠宝商地址,珠宝商所在城市,电话
FROM 珠宝商信息
WHERE NOT EXISTS
(SELECT *
FROM 销售信息
WHERE 珠宝商编号=珠宝商信息.珠宝商编号
)
AND 珠宝商所在城市<>'北京市'
ORDER BY 珠宝商所在城市
3.1.3使用比较运算符
子查询可以由1个比较运算符引入。与使用关键字IN引入的子查询1样,由比较运算符与1些关键字引入的子查询返回1个值列表。
SQL支持的在子查询中使用到的比较运算符有ANY、SOME和ALL。ANY和SOME关键字只重视是不是有返回值满足搜索条件,它们的含义相同,可以相互替换使用。ALL关键字只重视是不是所有的返回值都满足搜索条件。
举例来讲,在数据库”销售管理系统“的”出库单明细信息“表中,查询”出库商品金额“大于任意1个”入库单明细信息“表中”入库商品金额“高于10000的出库单的相干信息。
SELECT *
FROM 出库单明细信息
WHERE 出库单商品金额 > ANY
(SELECT 入库商品金额
FROM 入库单明细信息
WHERE 入库商品金额 > 10000)
为了方便学习二者使用情况,我们进行对照学习,下面就举1个相同的例子,在数据库”销售管理系统“的”出库单明细信息“表中,查询”出库商品金额“大于所有”入库单明细信息“表中”入库 商品金额“低于10000的出库单的相干信息。
SELECT *
FROM 出库单明细信息
WHERE 出库单商品金额 > ALL
(SELECT 入库商品金额
FROM 入库单明细信息
WHERE 入库商品金额 < 10000)
3.2返回单个值的子查询
这样的子查询只返回1个值,然后将1列值与单个子查询返回的值进行比较,这时候可使用比较运算符。
由未修改的比较运算符(后面不跟ANY或ALL的比较运算符)引入的子查询必须返回单个值而不是值列表。
举例来讲,在”珠宝销售系统“中,查询与”消费者编号“为27的消费者同处1个城市的珠宝商相干信息,要求以列”珠宝商姓名“、”珠宝商地址“、”珠宝商所在城市“和”电话“的情势返回查询结果。
SELECT 珠宝商姓名,珠宝商地址,珠宝山所在城市,电话
FROM 珠宝商信息
WHERE 珠宝商所在城市=
(SELECT 消费者所在城市
FROM 顾客信息
WHERE 消费者编号=27
)
由于聚集函数可以返回1个单值,所以可以在子好擦寻中包括聚集函数。
举例来讲,在数据库”销售管理系统“中的”商品信息“表中,查询单价大于平均价格的商品的相干信息。要求以列”商品名称“、”产地“和”单价“的情势返回查询结果。
SELECT 商品名称,产地,单价
FROM 商品信息
WHERE 单价>
(SELECT AVG(单价)
FROM 商品信息
)
3.3使用相干子查询
在之前说明的子查询中,SQL只对子查询进行1次评估,然后替换搜索条件中的子查询结果,和根据搜索条件的值来对外部查询进行评估。但是,有些子查询的履行进程依赖于值得外部查询。结果是,反复的履行子查询,对外部查询选择的每行都履行1次。这样的子查询称为相干子查询。
由于相干子查询依赖于其结果的外部查询,所以他们不能进行单独评估。相干子查询的WHERE子句援用外部查询的FROM子句中的表。也就是说,相干子查询是1个在外部查询中包括表的援用外部查询的FROM子句中的表。也就是说,相干子查询是1个在外部插叙中包括表的援用的子查询,它不能再外部查询之前求值。
举例来讲,在”销售管理系统“中,查询由”供应商名称“为”北京世纪葵花“提供的商品的相干信息。要求以列”商品名称“、”产地“和”单价“的情势返回查询结果。
SELECT 商品名称,产地,单价
FROM 商品信息
WHERE '北京世纪葵花' IN
(SELECT 供应商名称
FROM 供应商信息
WHERE 商品信息.供应商编号=供应商信息.供应商编号
)
在相干子查询中,也能够为表指定表名,利用别名来代替表名。但是如果对同1个表进行相干子查询时,则必须为表指定别名。
举例来讲,在”珠宝营销系统“的”顾客信息“表中,查询顾客所居住的不同城市。
SELECT DISTINCT A.消费者所在城市
FROM 顾客信息 A
WHERE A.消费者所在城市 IN
(SELECT B.消费者所在城市
FROM 顾客信息 B
WHERE A.消费者编号<>B.消费者编号
)
上述子查询的语句同等于下面的自连接查询语句(关于自连接的相干介绍,请查阅这里),将该自连接查询语句运行后,其查询结果与上述的子查询语句的结果完全相同。
SELECT DISTINCT A.消费者所在城市
FROM 顾客信息 A INNER JOIN 顾客信息 B
ON A.消费者所在城市=B.消费者所在城市
AND A.消费者编号<>B.消费者编号
3.4使用嵌套子查询
前面介绍了只有1个子查询的SELECT语句,但是,在SELECT语句中还可以包括多个子查询,即1个子查询中还包括其它子查询,这样的查询称为嵌套子查询。
在SELECT语句中使用多个子查询的1种方法是把它们作为这个语句的不同组成部份。例如,1个WHERE子句可能含有两个关键字来引导两个子查询语句。还有1种在SELECT语句中使用多个子查询的方法是把1个子查询嵌套到另外一个子查询中。
举例来讲,在数据库“销售管理系统”中,查询客户在2005年6月1日至2005年12月31日之间购买商品时,接待客户的业务员的相干信息。要求以列“业务员姓名”、“家庭住址”和“电话”的情势返回查询结果。
SELECT 业务员姓名,家庭住址,电话
FROM 业务员信息
WHERE 业务员编号 IN
(SELECT 所属业务员编号
FROM 客户信息
WHERE 客户编号 IN
(SELECT 客户编号
FROM 出库单信息
WHERE 出库日期 BETWEEN '2005⑹⑴' AND '2005⑴2⑶1'
)
)
上述语句运行顺序为:绿色部份,紫色部份,蓝色部份,即由内到外,逐次查询。
3.5使用子查询修改数据
子查询还可以用来修改数据库中的数据。使用子查询修改数据主要是通过下面3个关键字来实现INSERT、UPDATE和DELETE。
3.5.1插入数据
INSERT语句可以向已有表中添加数据。它可以直接向表中插入数据,也能够用视图向隐含表中插入数据。如果要在INSERT语句中使用子查询,必须把它作为VALUES子句中定义的1个值。
举例来讲,在数据库“销售管理系统”中的“业务员信息”表中增加1名业务员的1行新数据,该行数据中“业务员编号”为1009,“业务员姓名”、“家庭住址”和“电话”来自“客户信息”表中“客户编号”为1008的“客户姓名”、“客户地址”和“联系电话”。
INSERT INTO 业务员信息 VALUES
(1009,
(SELECT 客户姓名
FROM 客户信息
WHERE 客户编号=1008),
(SELECT 客户地址
FROM 客户信息
WHERE 客户编号=1008),
(SELECT 联系电话
FROM 客户信息
WHERE 客户编号=1008)
)
再履行下面语句进行查看:SELECT * FROM 业务员信息
在INSERT语句中使用子查询向表中插入数据时,必须肯定子查询的返回结果只能返回1个值。如果返回的查询结果中多于1个值,就会出现毛病,并且子查询中返回的单个值必须和目标列的数据类型及其他限制1致。
3.5.2更新数据
UPDATE语句允许修改表中已有数据。和INSERT语句1样,可以直接对表中的数据进行修改。如果视图可更新,也能够通过视图进行修改。要在UPDATE语句中使用子查询,子查询则由WHERE子句引入。
举例来讲,在上个例子中,将数据库“销售管理系统”的“业务员信息”表中添加的那1行数据所对应的“业务员姓名”、“家庭住址”和“电话”分别更改成“赵奇”、“北京市西城区”和“13585452343”。
UPDATE 业务员信息
SET 业务员姓名='赵奇',家庭住址='北京市西城区',电话='13585452343'
WHERE 业务员姓名=
(SELECT 客户姓名
FROM 客户信息
WHERE 客户姓名='薛红林'
)
再履行下面语句进行查看:SELECT * FROM 业务员信息
3.5.3删除数据
DELETE语句实现的功能是删除数据库表中的数据。在DELETE语句中的WHERE子句中使用子查询与UPDATE语句相似。
举例来讲,将数据库“销售管理系统”的“业务员信息”表中插入的那1行数据删除。
DELETE 业务员信息
WHERE 业务员姓名=
(SELECT 客户姓名
FROM 客户信息
WHERE 客户编号=1008
)
4.学习小结
数据库的查操作是数据库的重点学习部份,在这几部份的学习和总结的进程中,深感乏力,不管知识体系的庞大还是其中相干联系的扑朔迷离,都是10分重要的,却也是最难以理解和掌握的。
自己也是用了半月的时间把数据库的查操作的总结用最后的时间总结了出来,做1分享,固然,不能不说的是,对数据库的相干知识,希望努力去实践,在操作中体会用法,以便更好地掌握其要领,也希望自己今后可以做到更好。