02 cathy 10 pascal 02 cathy 40 c 想要返回 01 john 50 02 cathy 50 语句为:
Select sno,sname,sum(grade) from student Group by sno;//非法写法
Select sno,min(sname),sum(grade) from student Group by sno;//建议用这种写法,效率高些 或 Select sno,sname,sum(grade) from student
Group by sno,sname;
又如:SELECT CNO,AVG(GRADE) FROM SC GROUP BY CNO; //查询每一门课的课程号和平均成绩。
SELECT SSEX,COUNT(*) FROM STUDENT GROUP BY SSEX; //按SSEX分组查出:不同性别,各性别的人数 十二、 数据分组深入HAVING
集合函数如果要作为条件,只能出现在HAVING子句中,不允许出现在WHERE中。 格式:SELECT列名 [列别名],列名 [列别名],…… 集合函数(列名 [列别名] ) FROM表名 [表别名],表名 [表别名],表名 [表别名] WHERE 条件表达式
GROUP BY列名、列名、……列名 HAVING 集合函数() 表达式; 例如: SELECT NAME,COUNT(*)
FROM STUDENT GROUP BY NAME HAVING COUNT(*)>1; //查出重名的名和此姓名的总人数
Select name,count(*) from student //非法写法 Where count(*)>1 Group by name
进一步应用,将有重名的人的所有信息全部显示出来 Select * from student
where name in (select name
from student group by nane having count(*)>1)
SELECT SNO,AVG(GRADE) FROM SC
GROUP BY (SNO)
HAVING AVG(GRADE)>=75;
//查出平均分数在75以上的学生学号
T( NAME,BOOK)
6
张三 化学 张三 物理 李四 数学
SELECT NAME ,COUNT(*) FROM T GROUP BY NAME HAVING COUNT(*)>1; 查询借书超过1本的人以及本数。
★Where子句与having短语的区别在于作用对象不用。where子句作用与基本表或试图,从中选择满足条件的元组。Having短语作用于组,从中选择满足条件的足。
特别说明: Having子句允许用户指定对一个记录组的搜索条件,而通常的where 查询条件只针对单纪录,不针对记录组。 练习: Person
child_no child_name father_no father_name child_sex 1 张三 3 王五 f 2 李四 3 王五 m 3 王五 无父亲 m 4 姚六 3 王五 m 5 赵七 无父亲 f 问题:找出所有父亲及他的孩子数量。
问题:找出孩子最多父亲有几个孩子(一数字)。 问题:找出孩子最多的那些父亲。 问题:找出兄弟姊妹最多的那些人。 问题:找出兄弟最多的那些人所有兄弟。 问题:找出兄弟最多的那些人所有兄弟姐妹。 解:①select fno,min(fname),count(*) From person
Where fname is not null Group by fno
②select max(count(*)) From person Group by fno
③select fno,min(fname),count(*) From person
Where fname is not null Group by fno
Having count(*)=(select max(count(*))
From person Group by fno )
④select * //兄弟姐妹最多的人的信息 From person
Where fno in(select fno //兄弟姐妹最多的人的父亲
From person Group by fno
Having count(*)=(select max(count(*)) //兄弟姐妹最多的数量
From person
Where fname is not null Group by fno
)
7
)
⑤select * //兄弟最多的人的兄弟信息 From person Where sex= ' m'
And fno in(select fno //兄弟最多的人的父亲
From person Where sex= ' m' Group by fno
Having count(*)=(select max(count(*)) //兄弟最多的数量
From person
Where fname is not null
And sex= ' m' Group by fno )
)
⑥select * //兄弟最多的人的兄弟姐妹信息 From person
Where fno in(select fno //兄弟最多的人的父亲
From person Where sex= ' m' Group by fno
Having count(*)=(select max(count(*)) //兄弟最多的数量
From person Where sex= ' m' Group by fno )
)
十三、 连接查询:
例1:
SELECT STUDENT.SNO,NAME,CNO,GRADE FROM STUDENT,SC
WHERE STUDENT.SNO=SC.SNO;
//查询学生学号,姓名,选修课号,成绩
例2:
A (Aname, Abook)
张三 语文 李斯 数学 李斯 英语 王务 地理 b (Aname,B credit) 张三 80 李斯 70 王务 55 李斯 90
语句select * from a ,b where a.Aname = b.Aname
order by Aname; 返回6行数据
8
张三 语文 张三 80 李斯 数学 李斯 70 李斯 数学 李斯 90 李斯 英语 李斯 70 李斯 英语 李斯 90 王务 地理 王务 55
十四、 表别名的使用:
作用1:书写方便
例如:SELECT S1.SNO,NAME,CNO
FROM STUDENT S1,SC S2 WHERE S1.SNO=S2.SNO;
作用2:相同表进行连接查询
例如:SELECT S1.SNO,S1.NAME,S2.SNO,S2.NAME FROM STUDENT S1,STUDENT S2
WHERE S1.SAGE=S2.SAGE AND S1.SSEX=’男’ AND S2.SSEX=’女’; //显示年龄相同的男生、女生学号与姓名 例如:
一个表的行与自己的其他行数据进行计算。 表T(name,age,father)
H 22 T K 23 D w 50 F L 23 W T 51 R R 70 s
语句:Update t t1
Set age=(select age from t t2 where t1.father=t2.name)
Where exists (select 1 from t t2 where t1.father=t2.name); //Where father in (select name from t);
//如果有父亲的年龄,用父亲的年龄代替他的年龄 特别注意,不要忘记给update语句加上相应的where条件 执行后返回结果为: name,age,father
H 51 T K 23 D w 50 F L 50 W T 70 R R 70 s
比如有:用户表TDefUser(userid,address,phone),
消费表TAccConsume(userid,time,amount)
消费表聚集索引是userid,time
数据(注意因为有聚集索引,实际存储也是按以下次序的) 1 2006-1-1 200 1 2006-1-2 300 1 2006-1-2 500
9
1 2006-1-3 2000 1 2006-1-3 2000 1 2006-1-4 400 1 2006-1-5 500 2 2006-1-1 200 2 2006-1-2 300 2 2006-1-2 500 2 2006-1-3 2000 2 2006-1-3 6000 2 2006-1-4 400 2 2006-1-5 8000 3 2006-1-1 7000 3 2006-1-2 30000 3 2006-1-2 50000 3 2006-1-3 20000 语句:
select * from TDefUser
where exists (select 1 from TAccConsume
where TDefUser.userid=TAccConsume.userid and TAccConsume.amount>5000)
对于userid=1,需要找所有记录,才返回false,与第三个语句的效率差不多 对于userid=2,找到2006-1-3的记录,就返回true,比第三个语句的效率高 对于userid=3,第一条记录就返回true,比第三个语句的效率高
语句
select * from TDefUser
where userid in (select userid from TAccConsume where TAccConsume.amount>5000)
返回空记录集 2 2 3 3 3 3
再判断 语句
select * from TDefUser
where userid in (select userid from TAccConsume where userid=TDefUser.userid and amount>5000)
对于userid=1,需要找所有记录,返回空记录集,比较判断 对于userid=2,需要找所有记录,返回记录集 2 2
,比较判断
对于userid=3需要找所有记录,返回记录集 3
10