精通SQL---结构化查询语言详解

 

子查询(subquery),其结果用来作为另一个查询的参数。

 

在多表查询中使用子查询:

 

SELECT SNO,SNAME,MARK

FROM  STUDENT

WHERE CNO=(SELECT CNO FROM COURSE WHERE CNAME='计算机入门')

 

在子查询中使用聚合函数

 

SELECT    TNO,TNAME,DNAME,AGE

FROM    TEACHER

WHERE     AGE > (SELECT AVG(AGE) FROM TEACHER)

ORDER BY AGE

如果建立了子查询,且该子查询返回的是单一值,就可以使用任何一种比较运算符比较列值。另外,不仅限于比较数字,也可以比较字符串。

子查询不仅可以在WHERE中使用,还经常使用在SELECT子句中

SELECT    TNO,TNAME,DNAME,CNO,

                    (SELCET COUNT(*)    FROM STUDENT WHERE CNO=TEACHER.CNO) AS S_NUN

FROM     TEACHER

ORDER BY S_NUN

在SELECT 子句中使用子查询时,子查询必须返回单值。

一个子查询 除了可以产生一个单一值外,也可产生一个关系,该关系 可以包含若干元组。

 

IN子查询:(NOT IN)

用于集合成员的测试,可以实现集合交和集合差运算

SELECT    SNAME,DNAME,CNO,MARK

FROM    STUDENT

WHERE    SNO IN (SELECT SNO FROM STUDENT WHERE MARK<60)

ORDER BY     SNAME

EXISTS 子查询:(NOT EXISTS)

只需要子查询返回一个TRUE或者FALSE,子查询数据内容本身并不重要。可以实现两表交集

SELECT    TNO,TNAME,DNAME,CNO

FROM    TEACHER AS T

WHERE    EXISTS (SELECT * FROM STUDENT WHERE CNO=T.CNO)

ORDER BY    TNO

 

SOME/ALL子查询:

数量词SOME,ANY和ALL则允许使用比较运算符,将单值与子查询返回的值加以比较,而这里的子查询返回的结果可以是多行的。SOME和ANY功能相同

SELECT    TNO,TNAME,DNAME,AGE

FROM    TEACHER

WHERE    AGE<ALL(SELECT AGE FROM TEACHER WHERE DNAME='计算机')

AND    DNAME<>'计算机'

ORDER BY    AGE

这个例子也可以采用聚焦函数实现

SELECT    TNO,TNAME,DNAME,AGE

FROM    TEACHER

WHERE    AGE<(SELECT MIN(AGE) FROM TEACHER WHERE DNAME='计算机')

AND DNAME<>'计算机'

ORDER BY     AGE

实际上,用聚集函数实现子查询 通常比直接用SOME或ALL查询效率要高。

 

 

UNIQUE子查询

用来测试集合是否存在重复元组。返回的也是TRUE或FALSE

SELECT CNO,CNAME,CTIME,CTEST

FROM    COURSE

WHERE    UNIQUE(SELECT SNO FROM STUDENT WHERE CNO=COURSE.CNO)

ORDER BY CNO

SQL SEVER中没有提供对UNIQUE判式的支持,可以采用聚合函数

SELECT CNO,CNAME,CTIME,CTEST

FROM COURSE

WHERE (SELECT COUNT(*) FROM STUDENT WHERE CNO=COURSE.CNO)=1

ORDER BY CNO

相关子查询:

子查询的执行要依赖于上一层查询元组的当前值。

下面是用WHERE子句实现:

SELECT CNO,CNAME,CTIME,CTEST

FROM    COURSE

WHERE    '李华'IN (SELECT SNAME FROM STUDENT WHERE CNO=COURSE.CNO)

ORDER BY     CNO

 

比较运算符引入相关子查询

SELECT SANEM,DNAME,CNO,MARK

FROM    STUDENT AS S

WHERE    (SELECT CTEST FROM COURSE WHERE CNO=S.CNO)<CAST ('2006-7-2' AS SMALLDATETIME)

ORDER BY SNAME

CAST运算符将时间字符串 "2006-7-2"转换为SMALLDATETIME型。

相同的功能:

SELECT SDAME,DNAME,C.CNO,MARK

FROM    COURSE AS C,STUDENT AS S

WHERE S.CNO=C.CNO

AND CTEST< CAST('2006-7-2' AS SMALLDATETIME)

ORDER BY C.CNO

 

HAVING子句中使用的相关子查询

SELECT T.DNAME

FROM TEACHER AS T

GROUP BY T.DNAME

HAVING COUNT(*)<(SELECT COUNT(*) FROM STUDENT WHERE CNO IN (SELECT CNO FROM TEACHER AS T2 WHERE T2.DNAME=T.DNAME))

ORDER BY T.DNAME

 

嵌套子查询:

SELECT *

FROM COURSE

WHERE CNO IN (SELECT CNO FROM TEACHER WHERE DNAME='计算机' AND NOT EXISTS(SELECT * FROM STUDENT

                            WHERE CNO=TEACHER.CNO AND MARK<60))

ORDER BY CNO

相同功能:

SELECT *

FROM COURSE

WHERE CNO IN(SELECT CNO FROM TEACHER WHERE DNAME='计算机')

AND

NOT EXISTS(SELECT * FROM STUDENT WHERE CNO =COURSE.CNO AND MARD<60)

ORDER BY CNO

 

使用子查询创建视图:

创建视图

CREATE VIEW VIEW_AVGMARK(CNO,AVG_MARK)

AS SELECT CNO,AVG(MARK)

FROM STUDENT

GROUP BY CNO

 

查询

SELECT CNO,CNAME,CTEST

FROM COURSE

WHERE CNO IN (SELECT CNO FROM VIEW_AVGMARK WHERE AVG_MARK>70)

ORDER BY CNO

 

树查询:

SQL SERVER没有。略

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值