2.数据检索|模糊查询|数据排序|数据分组| 常见问题0726

本文深入讲解了SQL查询的基础及高级技巧,包括数据检索、聚合函数、条件查询、模糊查询、空值处理、数据排序、数据分组及Having语句等关键概念。通过实例演示如何运用这些技巧解决实际问题。
 

难点====分组查询group by...having

        在分组查询中,查询的列名

        必须出现在group by后或者在聚合函数中

        --查询平均工资大于两千块钱的部门

        select department_id,avg(wages)

        from employee

        where department_id  is not null

        group by department_id

        having avg(wages)>2000

 

1. 数据检索

l       Top Distinct

l       Top 获取前几条数据

l       获得年纪最小的5个学生

l       获得年纪最大的10%的学生

l       Distinct 去除重复数据

l       select distinct sName from student

l       select distinct sName,sAge from student

l       DISTINCT是对整个结果集进行数据重复处理的,而不是针对某一个列

--Top distinct

select top 5 * from student

order by sAge

--获取前10%的学生

select top 10 percent sName,sAge

from student

 

select distinct sName from student

2.聚合函数

l       SQL聚合函数:MAX(最大值)、MIN(最小值)、AVG (平均值)、SUM (和)、COUNT(数量)

l       平均成绩select avg(english) from score

l       男学生出生日期的最大值和最小值:SELECT select max(sBirthday),min(sBirthday) from student where sSex='男'

聚合函数

        --avg() 平均值

        --sum   求和

        --count 求行数

        --min   求最小值

        --max   求最大值

select max(english)from score

select * from score

 

select sum(english)/count(*)from score

select count(*)from student where sSex='男'

 

select sName,sAge,sSex from student

where sAge between 20 and 30 and sSex='男'

带条件查询

        select 列 from 表 where 条件

        between...and...

•           select sName,sAge from student where sClassId=1 or sClassId=2 or sClassId=3

•         select sName,sAge from student where sClassId in (1,2,3)

 

带条件的查询-模糊查询

查询所有姓张的同学

Select * from student where left(sName,1)=‘张‘   看上去很美,如果改成查询名字中带亮的学生怎么做?

换一种做法 like 

l       Select  * from student where sName like ‘张%’    会吧所有姓张的都查询到,现在我想查询姓张并且名字是一个字的学生?

l       Select  * from student where sName like ‘%亮%’

通配符 %多字符匹配的通配符,它匹配任意次数(零或多个)出现的任意字符

通配符_ 单字符匹配,它匹配单个出现的字符

[] 只匹配一个字符  并且这个字符必须是[]范围内的    [0-9]  [a-z][abc]

--模糊查询

select left ('123',1)

select * from Student where left(sName,1)='张'

 

select * from Student where sName like '张%'

select * from Student where sName like '%亮%'

 

空值处理

数据库中,一个列如果没有指定值,那么值就为null,这个null和C#中的null,数据库中的null表示“不知道”,而不是表示没有。因此select null+1结果是null,因为“不知道”加1的结果还是“不知道”。

select * from score where english = null ;

select * from score where english != null ;都没有任何返回结果,因为数据库也“不知道”。

SQL中使用is null、is not null来进行空值判断: select * from score where english is null ; select * from score where english is not null ;

--null

select null+123

select * from score where english is not null

 

数据排序

ORDER BY子句位于SELECT语句的末尾,它允许指定按照一个列或者多个列进行排序,还可以指定排序方式是升序(从小到大排列,ASC)还是降序(从大到小排列,DESC)。

按照年龄升序排序所有学生信息的列表:SELECT * FROM  Student ORDER BY sAge ASC

按照英语成绩从大到小排序,如果英语成绩相同则按照数学成绩从大到小排序 :SELECT * FROM  Score ORDER BY english DESC,math DESC

ORDER BY子句要放到WHERE子句之后 : SELECT * FROM  Score where english>=60 and math>=60 ORDER BY english DESC,math DESC

--order by

select top 2 * from student

order by sAge desc

 

select * from student

order by sName desc

 

select * from score

order by english asc,math desc

 

select * from score

where english>60 and math>60

order by english desc,math asc

数据分组

l       出现聚合函数后要加group by 字句

l       select 语句中可以使用group by 子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息

l       按照班级进行分组统计各个班级的人数: select sClassId,count(sName) from student group by sClassId

l       GROUP BY子句必须放到WHERE语句的之后

l       没有出现在GROUP BY子句中的列是不能放到SELECT语句后的列名列表中的 (聚合函数中除外)

l       错误: select sClassId,count(sName),sAge from student group by sClassId(因为sAge没有出现在group by 之后)

l       正确: select sClassId,count(sName),avg(sAge) from student group by sClassId

--group by sClassId

--分组就是把sClassId相同值的那些行,合并为一行

--当有“每个”的含义的时候使用分组

 

--每个班有多少学生

select count(*),sClassId from student

group by sClassId

--第一个问题,使用group by后,select之后的列必须出现在group by字句中或者聚合函数中

select count(sId) as '个数',sClassId from student

where sSex='男'

group by sClassId

--出错,聚合函数不能出现在where字句中

select count(sId),sClassId,avg(sAge) from student

where avg(sAge)>20

group by sClassId

Having语句

Having 是Group By的条件对分组后的数据进行筛选

在Where中不能使用聚合函数,必须使用Having,Having要位于Group By之后,

查询班级人数超过三个人的班级

select sClassId,count(sName) from student group by sClassId having count(sName)>3

注意Having中不能使用未参与分组的列,Having不能替代where。作用不一样,Having是对组进行过滤。

--求平均年龄超过岁的那些班

--having对分组过后的数据进行筛选(和where的作用不同)

select count(sId),sClassId,avg(sAge)from student

group by sClassId

having avg(sAge)>20

select sClassId,count(sName) from student group by sClassId having sAge>30

//错,having是对分组后信息的过滤,能用的列和select中能用的列是一样。

//having无法代替where。

--求人数超过人的班

select count(sId),sClassId from student

group by sClassId

having count(sId)>5

--分组练习

--求男生和女生分别有多少人

select count(sId),sSex from student

group by sSex

 

--求每个班有多少男生

select count(sId),sClassId from student

where sSex='男'

group by sClassId

 

--求平均年龄小于的那些班

select count(sId),sClassId,avg(sAge)from student

group by sClassId

having avg(sAge)<22

 

以上都是要掌握的,下面是要了解的

l       联合结果集

简单的结果集联合:

select tName,tSex from teacher union

select sName,sSex from student

基本的原则:每个结果集必须有相同的列数;每个结果集的列必须类型相容。

select tName,tSex,-1 from teacher union

select sName,sSex,sClassId from student

 

    8、同时插入多条语句

        把查询到的结果插入到现有表中

            insert into 现有表

            select 字段

            from 表

        把现有表的数据插入到一个新表 

            select 字段

            into 新表

            from 表

        --把现有表的数据插入到新表(表不能存在)

        --select * into newStudent from student

        --把现有表的数据复制到一个已存在的表

        --insert into backupStudent select * from students

       

    9、合并查询union 去除重复项

        union all 不去除重复项 所以效率高

        一次插入多条数据

        insert into Score(studentId,english,math)

        select 1,80,100 union

        select 2,60,80

l       Union all

•         select tName,tSex from teacher union

•         select sName,sSex from student

UNION合并两个查询结果集,并且将其中完全重复的数据行合并为一条

•         select tName,tSex from teacher union all

•         select sName,sSex from student

Union因为要进行重复值扫描,所以效率低,因此如果不是确定要合并重复行,那么就用UNION ALL

 

--union

--列的个数一致,类型一致

--排序去除重复数据

select tName,tSex,-1 from teacher union

select sName,sSex,sClassId from student

--union all

--直接连接两个结果集

select tName,tSex from teacher union all

select sName,sSex from student

--要求在一个表格中查询出学生的英语最高成绩、最低成绩、平均成绩

select '最高成绩',max(english) from score union all

select '最低成绩',min(english) from score union all

select '平均成绩',avg(english) from score

 

 

--查询每位老师的信息,包括姓名、工资,并且在最后加上平均工资和最高工资

select tName,tSalary from teacher union all

select '平均工资',avg(tSalary) from teacher union all

select '最高工资',max(tSalary) from teacher

 

--一次插入多条数据

insert into Score(studentId,english,math)

select 1,80,100 union

select 2,60,80 union

select 3,50,59 union

select 4,66,89 union

select 5,59,100

 

select * from score

 

--把现有表中的数据插入到新表中(newStudent表不能存在)

--去除表中重复数据

select * into newStudent from student

select * from newStudent

 

--把现有表的数据复制到一个已存在的表

truncate table newStudent

insert into newStudent select sName, sAge, sNo, sBirthday, sClassId, sSex, sIntime, sPhone from student

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值