按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
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
…………………………………………………………Page 149……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
INPUT/OUTPUT
SELECT O。PARTNUM SUM O。QUANTITY*P。PRICE COUNT PARTNUM
FROM ORDERS O PART P WHERE P。PARTNUM = O。PARTNUM GROUP BY O。PARTNUM
HAVING SUM O。QUANTITY*P。PRICE 》 SELECT AVG O1。QUANTITY*P1。PRICE
FROM PART P1 ORDERS O1
WHERE P1。PARTNUM = O1。PARTNUM
AND P1。PARTNUM = O。PARTNUM)
PARTNUM SUM COUNT
10 8400。00 4
23 4906。30 2
76 19610。00 5
分析
子查询中不能只有
AVG(O1。QUANTITY*P1。PRICE)
因为子查询与主查询之间需要下边的关联语句
AND P1。PARTNUM = O。PARTNUM
将会计算每一组的平均值然后再与 HAVING SUM(O。QUANTITY*P。PRICE)》进行比较
技巧 当在相关查询中使用 GROUP BY 和 HAVING 子句时 在 HAVING 子句中的列必需
在 SELECT 或 GROUP BY 子句中存在 否则你将会收到一行非法引用的信息 因为这时
与子查询对应的是每一组而不是每一行 对于组你无法进行比较操作
EXISTS ANY ALL 的使用
EXISTS ANY 和 ALL 关键字的用法不像它看上去那么直观 如果子查询返回的内容
为非空时 EXISTS 返回 TRUE 否则返回 FALSE 例如
INPUT/OUTPUT
SELECT NAME ORDEREDON FROM ORDERS WHERE EXISTS
(SELECT * FROM ORDERS WHERE NAME ='TRUE WHEEL')
NAME ORDEREDON
TRUE WHEEL 15…MAY…1996
TRUE WHEEL 19…MAY…1996
149
…………………………………………………………Page 150……………………………………………………………
SQL 21 日自学通(V1。0) 翻译人 笨猪
NAME