SELECT查询总结

SELECT查询总结:
WHERE子句不能用聚集函数作为条件表达式。而HAVING子句可以。。

WHERE子句作用于基本表或视图,HAVING子句作用于组,选择满足条件的组。

使用GROUP BY子句进行分组时,聚集函数作用对象为每个组。

HAVING的使用:

SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*> 3;

聚集函数遇到空值时,除了COUNT(*)外,都跳过空值而处理非空值。
NATURAL JOIN--自然连接:合并同名列。相对于直接笛卡尔积然后WEHERE等值连接要效率高。
SELECT SUM(qty) 总量,sno 供应商号
FROM
 spj NATURAL JOIN s
GROUP
 BY sno
HAVING SUM(qty)>1000
ORDER BY SUM(qty) DESC;

外连接:等值连接和自然连接都会将属性列不同的结果舍弃,比如S1表有个记录字段学号为025135,在S2表中没有这个学号,则025135这个记录在S1与S2做等值连接或自然连接的时候就会自动舍弃。外连接则将无匹配结果项也显示,笛卡尔积中无匹配列的值以NULL代替。

ORDER BY子句不能用在子查询的SELECT语句中,ORDER BY子句只能对最后结果排序。
相关子查询:有点类似如下的嵌套的循环:
for(int i = 0 ; i < NUM ; i++)
{
 for (int j = 0 ; j < i ;j++)
 {do..something;}
}
内层根据外层的i,得到j的范围,比如:

SELECT Sno, Cno
FROM SC x
WHERE Grade >= (SELECT AVG(Grade)
                                
FROM SC y
                                
WHERE y.Sno = x.Sno);

这里的Sno相当于i,Grade就相当于j了。可能的过程是:从外层查询中取出SC的一个元祖x,将元祖x的Sno值传送给内层查询,执行内层查询,得到值,用该值代替内层查询,得到外层查询。

不相关子查询:

SELECT  Sno,Sname,Sdept
FROM
 Student
WHERE Sdept IN

               (
SELECT  Sdept
                
FROM
 Student
                
WHERE Sname = '刘成';

 

=ANY等价于IN,<ANY等价于<MAX,<>ALL等价于NOT IN,<ALL等价于<MIN。
用聚集函数实现子查询通常比直接用ANY或ALL查询效率高。
由EXISTS引出的子查询,其目标列表达式通常都用*,因为EXISTS的子查询只返回真值或假值,给出列名无实际意义。
参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同。
使用UNION将多个结果合并起来时,系统会自动去掉重复元组。如果要保留重复元组则用UNION ALL操作符。

几种查询之间的转换:

集合运算与AND
[实例]
1.查询计算机科学系的学生与年龄不大于19岁的学生的交集。
集合运算:

SELECT   *
FROM  Student
WHERE  Sdept  =   ' CS '
INTERSECT
SELECT   *
FROM  Student
WHERE  Sage <= 19 ;

用AND:

SELECT   *
FROM  Student
WHERE  Sdept  =   ' CS '   AND
      Sage 
<=   19 ;

2.查询计算机科学系的学生与年龄不大于19岁的学生的差集。
集合查询:

SELECT   *
FROM  Student
WHERE  Sdept = ' CS '
EXCEPT
SELECT   *
FROM  Student
WHERE  Sage  <= 19 ;

 

用AND(相当于查询计算机系中年龄大于19岁的学生):

SELECT   *
FROM  Student
WHERE  Sdept  =   ' CS '   AND  Sage  >   19 ;

子查询与连接:

[实例]
1.查询与刘晨同一个系的学生
子查询:

SELECT  Sno,Sname,Sdept
FROM  Student
WHERE  Sdept  IN
            (
SELECT  Sdept
             
FROM  Student
             
WHERE  Sname = ' 刘晨 ' );

//当然这边IN可以用=号代替

连接:

SELECT  S1.Sno,S1.Sname,S1.Sdept
FROM  Student S1,Student S2
WHERE  S1.Sdept  =  S2.Sdept  AND
      S2.Sname
= ' 刘晨 ' ;

//可能的过程是:Student表跟自身做笛卡尔积,S1|S2,得到的结果中筛选S2.Sname是刘晨的记录,再在记录中筛选S1.Sdept=S2.Sdept的记录。


带IN谓词、比较运算符、ANY和ALL谓词的子查询都能用带EXISTS谓词的子查询等价替换:
[实例]
题目同上一个:

用EXISTS:

SELECT  Sno,Sname,Sdept
FROM  Student S1
WHERE   EXISTS
       (
SELECT   *
        
FROM  Student S2
        
WHERE  S2.Sdept = S1.Sdept  AND
              S2.Sname
= ' 刘晨 ' );

//可能的过程是:从S1中取一条记录,得到他的Sdept,然后找S2中有同样Sdept并且Sname为刘晨的记录是否存在,存在则输出S1中的匹配项。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值