友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
SQL 21日自学通(V3.0)(PDF格式)-第30部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
WHERE O。PARTNUM = P。PARTNUM))
NAME ADDRESS STATE ZIP
BIKE SPEC CPTSHRIVE LA 45678
LE SHOPPE HOMETOWN KS 54678
JACKS BIKE 24EGLIN FL 34567
分析
注意一下圆括号最里边的内容 你会发现类似的语句
SELECT AVG(O。QUANTITY * P。PRICE)
FROM ORDERS O PART P WHERE O。PARTNUM = P。PARTNUM
结果传入的语句与你以前使用的 SELECT 语句有一些不同之处
SELECT O。NAME FROM ORDERS O PART P WHERE O。PARTNUM = P。PARTNUM
AND O。QUANTITY * P。PRICE》(。。。)
注意 SELECT 子句已经被改为返回单一的 NAME 列 运行该查询你会得到下表
NAME
LE SHOPPE
BIKE SPEC
LE SHOPPE
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
…………………………………………………………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
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!