技术应用
TECHNICAL APPLICATION
摘 要:在SQL 中,使用子查询进行合并查询可以提高查询效率,简化查询代码。本文就SQL 合并查询的用法结合实例从四个方面进行了探讨。
关键字:SQL 语句 合并 查询 子查询在对数据库的查询时,有时候复杂的查询条件需要我们对表进行反复的查询,在多张表中的数据来回穿梭,使我们不胜厌烦。其实我们可以合理的使用SQL 中的子查询将多个查询结果进行合并查询,也许这样我们只需要一条语句就可以解决棘手的查询问题。SQL 的这项功能可以使我们在一组结果中查询,创造性地给结果组加以限定,或是在向数据库的单一调用中将结果与一个无关系的查询做相关。本文将给出几个子选择的例子并就何时使用他们进行讨论。
一、使用比较运算符的查询合并
对于如下关系模式
Books(bookID,title,ISBN,author,unitprice,categorycode)Orders(orderID,orderdate,shipdate,customerID)Orderitems(orderID,bookID,quantity,price,total)Categories(categorycode,categoryname)Customers(customerID,customername)
查询ISBN 是“711116220x”的图书销售的订单号和销售数量。
SELECT orderID, quantity FROM OrderItems WHERE bookID = ( SELECT bookID FROM Books WHERE ISBN='711116220x ')
在该查询中,订单号和销售数量字段处于orderitems 表,而ISBN 字段处于books 表,需要先从books 表中得到ISBN='711116220x'的图书号,然后再从orderitems 表中查询出改图书号图书的订单号和销售数量。使用子查询可以将这个两个查询合并,形成一个嵌套查询,执行的时候先执行内层子查询,然后执行外层查询。但是使用比较运算符的子查询的结果必须要求是唯一的单值,即子查询的结果为单行单列的值,否则运行时会出现错误。当然上述查询如果比较运算符是“=”号的号,我们也可以使用join 将两表连接后再进行条件查询,同样可以得到相同的结果,但如果比较运算符是其他符号的join 连接查询就不能实现了,必须使用子查询了。比如下个例题:
显示单价高于平均单价的图书的详细信息。SELECT * FROM Books
WHERE unitPrice>( SELECT AVG (unitPrice) FROM Books)
由于比较运算符用的是大于号,因此不能使用join 连接查询得到结果。
二、使用运算符IN 的查询合并
当子查询的结果不唯一的时候,不能使用比较运算符“=”进行查询合并,而应该使用运算符IN。
SQL 合并查询用法之探讨
文/张捷
显示书名中包含字符串ASP 的图书的销售订单号和销售数量。SELECT orderID, quantity FROM OrderItems
WHERE bookID IN ( SELECT bookID FROM Book WHERE title LIKE '%ASP%')
因为可能有多本图书的书名中包含字符串“ASP”,所以子查询中的结果可能是多个值,这个时候不能再子查询前使用比较运算符,而应该使用运算符IN,将子查询的结果作为一个集合,在这个集合中进行搜索。
三、在select 子句中进行合并查询
有时候需要将一个子查询的结果作为最终结果组的一部分来返回。这个功能经常被合计函数所使用。通常地,对其他表格的访问可以作为我们查询的一部分。下一个例子将返回所有图书的书号、书名、单价以及销售总量。以下是查询语句:
SELECT bookID, title, unitPrice, (SELECT SUM(quantity) FROM OrderItems i WHERE i.bookID=b.bookID) AS 销售总量
FROM Books b
合并查询中的关键词ANY 和ALL
当子查询的结果是多值时,使用ANY 表示匹配子查询中的任意一个值,使用ALL 表示匹配子查询的所有值。
以下两个例子说明其用法:
对于那些比类别代号为FI01的任意一本图书的单价高的图书,显示其书号和书名。
SELECT bookID, title FROM Books
WHERE unitPrice>ANY ( SELECT unitPrice FROM Books WHERE categoryCode='FI01')实际上,“>ANY”可以理解为大于最小的值,“ 有时我们需要通过多种途径来访问相同的数据,而且需要对结果进行匹配(或相关)来得到值的交叉区。关键词EXISTS 的作用是用来检验子查询的结果是否为空,如果非空,则EXISTS 运算返回True,否则返回False。下面例题将查询2009年以后购买过图书的顾客的编号和姓名。 SELECT c.customerID, c.customerName FROM Customers c WHERE EXISTS ( SELECT * FROM Orders o WHERE o.orderDate>='01/01/09' AND c.customerID=o.customerID) (下转第57页) Switch#confi gure terminal Switch(confi g)#hostname Switch-A Switch-A(confi g)#vlan 10 Switch-A(confi g-vlan)#name test10 Switch-A(confi g-vlan)#end Switch-A#confi gure terminal Switch-A(confi g)#interface fastethernet 0/2 Switch-A(confi g-if)#switchport access vlan 10 重复以上命令,分别将f0/3~ f0/6同时添加到VLAN 10中。 在Switch-A上创建VLAN 20,并将f0/7~f0/12端口分配添加到VLAN 20中。 Switch-A#confi gure terminal Switch-A(confi g)#vlan 20 Switch-A(confi g-vlan)#name test20 Switch-A(confi g-vlan)#end Switch-A#confi gure terminal Switch-A(confi g)#interface fastethernet 0/7 Switch-A(confi g-if)#switchport access vlan 20 重复以上命令,分别将f0/8~ f0/12添加到VLAN 20中。 在Switch-A上将与Switch-C进行级联的端口f0/1设置为tag模式。 Switch-A#confi gure terminal Switch-A(confi g)#interface fastethernet 0/1 Switch-A(confi g-if)#switchport mode trunk 保存设置。 Switch-A#write memory 或 Switch-A#copy running-confi g starup-confi g (3)配置三层交换机Switch-C。 在Switch-C上将级联于Switch-A和Switch-B的端口f0/1和f0/2分别设为tag模式。 Switch(confi g)#hostname Switch-C Switch-C(confi g)# interface fastethernet 0/1 Switch-C(confi g-if)#switchport mode trunk Switch-C(confi g-if)#exit Switch-C(confi g)#interface fastethernet 0/2 Switch-C(confi g-if)#switchport mode trunk Switch-C(confi g-if)#end 通过以上的配置,位于同一VLAN(但位于不同的交换机)的PC1与PC3之间,以及PC2与PC4之间是可以进行通信的;而位于不同VLAN的主机(如PC1与PC2,PC3与PC4,PC1与PC4,PC2与PC3)之间是无法进行通信的。 在三层交换机Switch-C上设置VLAN之间的通信。 Switch-C(confi g)#vlan 10 Switch-C(confi g-vlan)#name test10 Switch-C(confi g-vlan)#exit Switch-C(confi g)#interface vlan 10 Switch-C(config-if)#ip address 192.168.1.254 255.255.255.0 Switch-C(confi g-if)#exit Switch-C(confi g)#vlan 20 Switch-C(confi g-vlan)#name test20 Switch-C(confi g-vlan)#exit Switch-C(confi g)#interface vlan 20 Switch-C(config-if)#ip address 192.168.2.254 255.255.255.0 Switch-C(confi g-if)#end 保存设置。(略) 3.4 VLAN综合应用结果验证 通过以上的配置,将凡是接入VLAN 10的主机IP地址设置为192.168.1.1~253,子网掩码设置为255.255.255.0,网关设置为192.168.1.254;将凡是接入VLAN 20的主机IP地址设置为192.168.2.1~253,子网掩码设置为255.255.255.0,网关设置为192.168.2.254。这时,再使用Ping命令进行测试,发现位于不同VLAN的主机之间都可以进行通信。 4、结束语 综上所述,利用Packet Tracer搭建的网络工程实践教学平台不仅功能强大,效果逼真,而且通过该平台的使用,学生先进行网络模拟仿真软件实验,再过渡到实物设备实验,极大地提高了同学们的学习兴趣和信心。实际上,在网络工程实践教学中应用网络仿真软件Packet Tracer,既能降低网络设备的投资成本,又能提高学生做实验的效率,能够更好地将理论教学和实践教学结合起来,更有利于培养学生的实际动手能力和创造能力,受到了广大师生的好评。 参考文献: [1] 徐洪学,郭秀英.仿真软件Packet Tracer在计算机网络工程课 程教学中的应用[J].沈阳教育学院学报,2010,(01) : 84-88 [2] 薛琴.基于Packet Tracer的计算机网络仿真实验教学[J].实验 室研究与探索,2010,(02) : 57-59 [3] 孔欣,李清平.基于Packet Tracer的跨路由器实现VLAN间 通信及分析[J].现代计算机(专业版),2010,(01):126-129. [4] 丁美荣.基于综合设计性实验项目的计算机网络实践教学[J]. 实验室研究与探索,2009 (3):118-120. [5] 罗拥军.网络设备配置基础[M].中国铁道出版社,2007. [6] 魏大新,李育龙.Cisco网络技术教程(第一版)[M].北京: 电子工业出版社,2004. 作者简介: 景朋森,工程师,硕士,南京工业大学电子与信息工程学院,长期从事于计算机网络等相关课程的实验教学工作。 王飞,讲师,硕士,南京工业大学电子与信息工程学院,长期从事计算机基础及网络数据库等相关课程的教学工作。 使用关键词EXISTS的子查询需要依次判断每条记录在where子句中通过EXISTS运算后是否返回True,如果返回True,查询结果中将包含该记录,否则不包含该记录。 从以上实例可以看出,使用SQL合并查询可以提高查询效率,简化查询代码,实现复杂条件的查询。因此掌握好合并查询,运用好子查询是一个合格数据管理员必须具备的能力。 参考文献: [1]袁红娟.浅析SQL中WHERE EXISTS子查询[J].长春师范 学院学报,2006, (06) . [2]李春艳,高伟.数据库中相关子查询的实现初探[J].唐山师范 学院学报,2009,(02). [3]茹蓓. SQL查询语句的优化[J].新乡教育学院学报,2006,(04).作者简介: 张捷,黄冈职业计算机学院计算机系教师,软件设计师,研究方向:软件开发、数据库。 (上接第54页) 57下载本文