数据库查询

对关系表实施的运算

(1)选择运算

根据给定条件,从二维关系表中将制定的记录挑选出来。

(2)投影运算

把二维关系中指定的列提取出来构成一张新表

(3)连接运算

 select 语句:用于数据查询

一、基本查询

1、选择列--select语句

select 列名1,列名2...

from 表名;

select 学号,姓名,性别,出生日期

from xs;

select *from xs;

给指定列起别名

select 列名 as 别名,列名as 别名...

from 表名;

查询计算列

select 姓名,总学分,总学分+10 as 提高后的总学分

from xs;

消除查询结果中的重复行

selectdistinct 列名

from 表名;

替换查询结果中的数据

select 学号,姓名,

case

when 总学分<50 then '不及格'

when 总学分>=50 and 总学分<60then '及格'

when 总学分>=60 then '优秀'

end as 等级

from xs;

使用聚合函数

selectmax(总学分),min(总学分)

from xs;

max(数值型列) 求这一列的最大值

min(数值型列) 求这一列的最小值

avg(数值型列) 求这一列的平均值

sum(数值型列) 求这一列的总和

count(*) 求的是表格中的记录的行数

count(指定某一列) 求的是指定列不为空的取值的个数(包括重复值)

count(distinct指定某一列) 指定列的取值去掉null值,去掉重复值后的记录的个数

 

2、选择运算---where子句

(1)关系表达式

>  >= <  <=  = <>(不等) !=   <=>(相等关系的比较)

select *

from xs

where 总学分>45;

select *from xs

where 备注<=>null;

select *from xs

where isnull;

或where is not null;

(2)逻辑表达式

select 学号,姓名,总学分

from xs

where 总学分>=40 and 总学分<=50;

select 学号,姓名,总学分

from xs

where 总学分<45 or 总学分>50;

and  &&

or   ||

not!

 

select 学号,姓名,总学分

from xs

wherenot(总学分>=40 and 总学分<=50);

 

select 学号,姓名,总学分

from xs

wherenot(学号='081101');或

select 学号,姓名,总学分

from xs

where !(学号='081101');

 

(3)betweenand

select 学号,姓名,总学分

from xs

where 总学分 between 45 and 50;

select 姓名,出生日期

from xs

where 出生日期 between '1989-01-01'and '1989-12-31';

select 姓名,出生日期

from xs

where 出生日期>'1989-01-01'and 出生日期<'1989-12-31';

 

(4)

select 姓名,总学分

from xs

where 总学分=38 or 总学分=40or 总学分=48;

select 姓名,总学分

from xs

where 总学分 in(38,40,48);

select 姓名,专业名,总学分

from xs

where 专业名='计算机'or 专业名='通信工程';

select 姓名,专业名,总学分

from xs

where 专业名 in('计算机','通信工程');

(5)模糊查询like '模式匹配字符串'

在'模式匹配字符串'中可以:%任意个任意的字符  _一个任意的字符

select 学号,姓名,总学分

from xs

where 姓名 like '王%';

select 学号,姓名

from xs

where 学号 like '__11__';

select 姓名,专业名

from xs

where 姓名 like '%#_%' escape '#';//转义字符

正则表达式

rlike '正则表达式的字符串'

或者 REGEXP'正则表达式的字符串'

select 学号,姓名,专业名

from xs

where 姓名 rlike '^王';

select 学号,姓名,专业名

from xs

where 姓名 rlike '林$';

rlike'.*'

rlike'^08.*08$'

rlike'a+'

rlike'[abc]'

rlike'[a-z]'

rlike'^[a-z]'

3、order by 对查询结果进行相应的排序

不会影响原有的顺序

select 列名1,列名2,...

from 表名

where 查询条件

order by 列名1[,列名2,...]

 

select 学号,姓名,出生日期

from xs

order by 出生日期;

desc 降序   asc  升序

 

select 学号,课程号,成绩

fromxs_kc

order by 课程号 asc,成绩desc;

如果order by子句中的排序列有多个,先按第一个指定列排序,在第一个指定列的值相同的情况下,再按第二个指定列

进行排序。

如果排序列有多个,每一列中需指明是升序还是降序

4、limit子句:限制的是显示的记录的行数,一般是和order by子句一起用。

limit[位置量,]显示记录的行数

select 学号,课程号,成绩

fromxs_kc

where 课程号='101'

order by 成绩 desc;

limit5;//取前五条记录

 

select 学号,课程号,成绩

fromxs_kc

where 课程号='101'

order by 成绩 desc

limit3,3;//前3表示位移量,从第四行记录开始

 

二、高级查询:多表连接查询、子查询、分组汇总

1、多表连接查询

姓名,课程名,成绩

xs   kc    xs_kc

 

(1) 全连接--不是标准呢的sql语句

select 列名1,列名2,...

from 表名1,表名2,...

where 表名1.列名=表名2.列名

查看:学生学号,姓名,选修的课程号,得分

      xs xs_kc xs    xs_kc      xs_kc

selectxs.学号,姓名,课程号,成绩

fromxs,xs_kc

where xs.学号=xs_kc.学号;

 

查看:学号、课程号、课程名、学时

     xs_kc kc xs_kc   kc   kc

select 学号,xs_kc.课程号,课程名,学时

fromxs_kc,kc

wherexs_kc.课程号=kc.课程号;

 

查看:学生姓名,课程名,得分

      xs      kc     xs_kc

select 姓名,课程名,成绩

fromxs,xs_kc,kc

where xs.学号=xs_kc.学号and kc.课程号=xs_kc.课程号;

 

(2)--标准的sql语句,推荐使用

内连接,外连接,自然连接,交叉连接

1)内连接:多个表通过连接条件中的共享列的值进行的比较连接

from 表名1[inner] join biao 表名2 on 连接条件

 

select 列名表

from 表名1 join 表名2

on 连接条件

 

selectxs.学号,姓名,课程号,成绩

from xsjoin xs_kc

using(学号)//on xs.学号=xs_kc.学号; using  共享

 

select 姓名,课程名,成绩

from xsjoin xs_kc

on xs.学号=xs_kc.学号  

join kc

on xs_kc.课程号=kc.课程号;

 

2)外连接:包含来自一张表的所有记录行和另一张的匹配记录行

左外连接 from 表名1 left[outer] join 表名2 on 连接条件

右外连接 from 表名1 right[outer] join 表名2 on 连接条件

查询:所有学生的学号,姓名以及他们所选课程的课程号,成绩

          xs xs_kc  xs                    xs_kc    xs_kc

 

selectxs.学号,姓名,课程号,成绩

from xsleft outer join xs_kc

on xs.学号=xs_kc.学号;

 

查询:学生选修课程的信息(学号、课程号、课程名),还有没有被学生选修的课程的情况

select 学号,xs_kc.课程号,课程名

fromxs_kc right outer join kc

on xs_kc.课程号=kc.课程号;

 

3)自然连接

 

naturaljoin 自然内连接

naturalleft join

naturalright join

 

selectxs.学号,姓名,课程号,成绩

from xsnatural join xs_kc;

 

4)交叉连接--笛卡尔积

 

selectxs.学号,姓名,课程号,成绩

from xscross join xs_kc

on xs.学号=xs_kc.学号;

 

2、嵌套查询 :在一个select语句中又包含另一个select语句

 

子查询一般都可以写成多表的连接查询

(1)子查询

select 学号,课程名

fromxs_kc natural join kc

where 课程名='计算机基础';

换一种思路:

 

select 学号

from xs_kc

where 课程号=(

       select 课程号

       from kc

       where 课程名='计算机基础'

)

第一步:执行子查询,101  只执行一次

第二步:执行外部查询,外部查询的查询条件好似依赖与子查询

查询: 所有成绩比平均成绩高的学生的学号,课程号

 

select 学号,课程号

fromxs_kc

where 成绩>(

       select avg(成绩)

       from xs_kc

)

子查询只做一次 75.2

 

 

(2)子查询的结果不是单列单行,而是单列多行。

解决办法:in

= ><  all或any子查询的结果集

选修了206的课程的学生的姓名

 

xs:学号,姓名

xs_kc:学号,课程号

 

select 姓名

from xsjoin xs_kc

on xs.学号=xs_kc.学号

where 课程号='206';

 

select 姓名

from xs

where 学号 in (select 学号from xs_kc where 课程号='206');

先执行子查询 ,也只执行一次

 

select 姓名

from xs

where 学号 not in (select 学号 from xs_kc where 课程号='206')

 

select 姓名

from xs

where 学号 = any (select 学号from xs_kc where 课程号='206');

 

select 姓名

from xs

where 学号 <>all (select 学号 from xs_kc where 课程号='206');

 

where 列名> all(子查询)    (1,8,9) 列的取值>9  查找的是比最大值还要大的记录行

<=all(子查询) (1,8,9)   列的取值<=1  查找的是比最小值还要小的记录行

>=all(子查询)

<=all(子查询)

=all(子查询)

<>all(子查询)

>any(子查询) (1,8,9) 查找的是比最小值大的记录行

<any(子查询) (1,8,9) 查找的是比最大值小的记录行

>any(子查询)

<any(子查询)

=any(子查询)

<>any(子查询) (1,8,9)

 

select 出生日期

from xs

where 专业名='计算机基础';

 

select 学号,姓名,专业名,出生日期

from xs

where 出生日期< all(

select 出生日期

from xs

where 专业名='计算机'

);

 

select 学号,姓名,专业名,出生日期

from xs

where 出生日期> all(

select 出生日期

from xs

where 专业名='计算机'

);

 

(3) whereexists(子查询)

如果子查询的结果集是非空,该判定为true,否则,该判定的false

 

查询: 选修206课程的学生姓名

select 姓名

from xs

whereexists (select * from sx_kc where 学号=xs.学号 and 课程号='206');

 

selectcount(*)

from xs;

3.分组group by

默认按升序显示分组的信息,可以使用desc来指明显示分组信息按降序

select 专业名,count(*)

from xs

group by 专业名;//分组

 

查询:每个学生的总成绩

查询:每门功课的平均分

 

select 学号,sum(成绩)

fromxs_kc

group by 学号;

 

select 课程号,avg(成绩)

fromxs_kc

group by 课程号;

 

select 课程号,学号,avg(成绩)

fromxs_kc

group by 课程号;

 

带有with rollup的分组汇总在原有的分组汇总的结果上又增加了汇总的信息。

select 专业名,性别,count(*)

from xs

group by 专业名,性别with rollup;

 

selectxs_kc.课程号,课程名,avg(成绩)

from kcjoin xs_kc

on kc.课程号=xs_kc.课程号

group by 课程号;

 

having子句,having条件:对分组汇总的信息进行筛选

selectxs_kc.课程号,课程名,avg(成绩)

from kcjoin xs_kc

on kc.课程号=xs_kc.课程号

group by 课程号

havingavg(成绩)>77.0;

 

where子句

having子句

对表中的记录按where中设定的条件进行筛选,然后,进行分组汇总,最后用having对分组汇总的结果再进行筛选

 

出生时间是:1989-10以后出生的学生按专业分组,统计每个专业的学生人数,将人数>3人的信息显示出来

select 专业名,count(*)

from xs

where 出生日期>'1989-10-01'

group by 专业名

havingcount(*)>3;

 

union

select 学号,姓名

from xs

where 专业名='计算机'

union

select 课程号,课程名

from kc

where 学分>4

order by1 desc

limit 5;

 

select 专业名,

 

引用一张表

(1)use数据库

select...

from 表名;

(2)

select...

from 数据库.表名;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值