按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
144
…………………………………………………………Page 145……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
NAME
BIKE SPEC
JACKS BIKE
我们曾经花过一些时间来讨论为什么子查询应该只返回一个数值 而这个查询返回
了多个数值则是显而易见的
将上述结果引入下边的语句
SELECT C。NAME C。ADDRESS C。STATE C。ZIP FROM CUSTOMER C
WHERE C。NAME IN (。。。)
分析
头两行没有什么特别的内容 在第三行时再次引入了关键字 IN 看一下第二天的 查
询简介 SELECT 语句的使用 IN 是一种允许你在子查询中进行多行输出的工具 就像
你原来记得的那样 它将返回与所列内容相匹配的记录 它的列出内容如下
LE SHOPPE
BIKE SPEC
LE SHOPPE
BIKE SPEC
JACKS BIKE
根据子查询的条件得到了下边的内容
NAME ADDRESS STATE ZIP
BIKE SPEC CPT SHRIVE LA 45678
LE SHOPPE HOMETOWN KS 54678
JACKS BIKE 24 EGLIN FL 34567
在子查询中使用关键字 IN 是非常普遍的 因为 IN 可以与一组数据进行对比 而且它
不会使 SQL 的引擎检查出其中有冲突或是不合适的地方
子查询也可以使用 GROUP BY 和 HAVING 子句 见下例
INPUT/OUTPUT
SELECT NAME AVG QUANTITY FROM ORDERS
GROUP BY NAME HAVING AVG QUANTITY 》 SELECT AVG QUANTITY
FROM ORDERS
NAME AVG
BIKE SPEC 8
JACKS BIKE 14
145
…………………………………………………………Page 146……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
分析
让我们来看一下这个查询在引擎中的工作过程 首先 请看子查询
INPUT/OUTPUT
SELECT AVG QUANTITY FROM ORDERS
该查询返回的结果为 6
而主查询的结果如下
INPUT/OUTPUT
SELECT NAME AVG QUANTITY FROM ORDERS GROUP BY NAME
NAME AVG
AAA BIKE 6
BIKE SPEC 8
JACKS BIKE 14
LE SHOPPE 4
TRUE WHEEL 5
在经过 HAVING 子句的检查后 该查询给出了两条大于平均 QUANTITY 的记录
INPUT/OUTPUT
HAVING AVG QUANTITY 》 SELECT AVG QUANTITY FROM ORDERS
NAME AVG
BIKE SPEC 8
JACKS BIKE 14
相关子查询
到现在为止 我们所写出的子查询都是独立的 它们都没有涉及到其它的子查询 相
关子查询可以接受外部的引用从而得到一些令人惊奇的结果 请看下边的这个查询
INPUT
SELECT * FROM ORDERS O WHERE 'ROAD BIKE' =
(SELECT DESCRIPTION FROM PART P
WHERE P。PARTNUM = O。PARTNUM)
OUTPUT
ORDEREDON NAME PARTNUM QUANTITY REMARKS
19…MAY…1996 TRUE WHEEL 76 3 PAID
146
…………………………………………………………Page 147……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
ORDEREDON NAME PARTNUM QUANTITY REMARKS
19…MAY…1996 TRUE WHEEL 76 3 PAID
17…JAN…1996 BIKE SPEC 76 11 PAID
17…JAN…1996 LE SHOPPE 76 5 PAID
1…JUL…1996 AAA BIKE 76 4 PAID
11…JUL…1996 JACKS BIKE 76 14 PAID
该查询实际上执行了类似下边的归并操作
INPUT
SELECT O。ORDEREDON O。NAME O。PARTNUM O。QUANTITY O。REMARKS
FROM ORDERS O PART P WHERE P。PARTNUM = O。PARTNUM
AND P。DESCRIPTION = 'ROAD BIKE'
OUTPUT
ORDEREDON NAME PARTNUM QUANTITY REMARKS
19…MAY…1996 TRUE WHEEL 76 3 PAID
1…JUL…1996 AAA BIKE 76 4 PAID
17…JAN…1996 LE SHOPPE 76 5 PAID
17…JAN…1996 BIKE SPEC 76 11 PAID
11…JUL…1996 JACKS BIKE 76 14 PAID
分析
事实上 除了命令不同以外 结果是一样的 相关查询的执行情况与归并非常相似
这个相关查询查找了在子查询中指定的内容 在本例中相关查询的由于语句所确定
WHERE P。PARTNUM = O。PARTNUM
当在子查询内部对 P。PARTNUM 和子查询外部的 O。PARTNUM 进行比较时 由于
O。PARTNUM 对于每一行均有一个不同的值 因此相关查询对每一行都执行了这一语句
下面是 ORDERS 表的详细内容
INPUT/OUTPUT:
SELECT * FROM ORDERS
ORDEREDON NAME PARTNUM QUANTITY REMARKS
15…MAY…1996 TRUE WHEEL 23 6 PAID
19…MAY…1996 TRUE WHEEL 76 3 PAID
2…SEP…1996 TRUE WHEEL 10 1 PAID
30…JUN…1996 TRUE WHEEL 42 8 PAID
30…JUN…1996 BIKE SPEC 54 10 PAID
147
…………………………………………………………Page 148……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
ORDEREDON NAME PARTNUM QUANTITY REMARKS
30…MAY…1996 BIKE SPEC 10 2 PAID
30…MAY…1996 BIKE SPEC 23 8 PAID
17…JAN…1996 BIKE SPEC 76 11 PAID
17…JAN…1996 LE SHOPPE 76 5 PAID
1…JUN…1996 LE SHOPPE 10 3 PAID
1…JUN…1996 AAA BIKE 10 1 PAID
1…JUL…1996 AAA BIKE 76 4 PAID
1…JUL…1996 AAA BIKE 46 14 PAID
11…JUL…1996 JACKS BIKE 76 14 PAID
它的内容对应着下边的查询
SELECT DESCRIPTION FROM PART P WHERE P。PARTNUM = O。PARTNUM
分析
该操作将返回符合条件 P。PARTNUM = O。PARTNUM 的 PART 表中的每一个
DESCRIPTION 之后 DESCRIPTION 又与下边的语句进行比较操作
WHERE ROAD BIKE =
由于每一行都进行了检查 所以这个相关查询可能会返回不止一条内容 不要以为返
回多列在 WHERE 中就是允许的了 它仍会被拒绝 本例中只所以会运行是因为
DESCRIPTION 是内容是唯一的 如下例 你试图将 PRICE 与 ROAD BIKE 进行比较
那么你将会收到如下信息
INPUT/OUTPUT
SELECT * FROM ORDERS O WHERE 'ROAD BIKE' =
(SELECT PRICE FROM PART P WHERE P。PARTNUM = O。PARTNUM)
conversion error from string 〃ROAD BIKE〃
这是又一个不能运行的例子
SELECT * FROM ORDERS O WHERE 'ROAD BIKE' =
(SELECT * FROM PART P WHERE P。PARTNUM = O。PARTNUM)
分析
在 WINDOWS 操作系统中将会导致一个一般保护性错误 SQL 引擎无法用=来关联所
有的行
相关查询也可以使用 GROUP BY 和 HAVING 子句 下边的查询是查找特定 PART 的
总价并对其按 PARTNUM 进行分组
148
…………………………………………………………Pag