SQL语言的数据查询

查询语句的语法

 select 列名... fromwhere 条件
 group by 分组条件 having 分组筛选条件 
 order by 排序条件 limit 限制个数;

where 条件

比较运算符
= 等值匹配
!= 不等值匹配
> 大于
< 小于
>= 大于等于
<= 小于等于

逻辑运算符
and	逻辑与(两个条件同时成立) 
or	逻辑或(两个条件有一个成立,结果就是真) 
not	逻辑非 (条件取反) 

like 模糊查询  其中匹配通配符
			 % 表示匹配0~多个任意字符
             通配符 _ 表示匹配1个任意字符列 
列between 值1 and 值2 等价于
			列 >= 值1 and 列 <= 值2, 
			注意小值要在前面,包含边界的值
列 in (值1,值2,... 值n)  等价于
			列=值1 or 列=值2 ... or 列=值n 			
			注意值列表的长度

group by 分组条件

聚集函数:
count(*)  表示求每组的个数
max(列) 求最大值
min(列) 求最小值
sum(列) 求和
avg(列) 求平均值

注意:
分组之后,

  • select子句中只能出现分组条件列和组函数,其他列不能出现在select中,
  • order by 子句中只能出现分组条件列和组函数,其他列不能出现在order by中,
    例如:
    select deptno,max(sal),ename from emp group by deptno; // ename不符合刚才的规定
    select deptno,max(sal) from emp order by ename; // 错误的
    having 分组筛选条件
where > group by > having
 > select > order by > limit // sql语句的执行顺序

同where功能一样,都是筛选条件,不过where是在分组前筛选,having是在分组后筛选。当需求要求分组后筛选时使用having,而分组前筛选时既可以使用where,也可以使用having,优先使用where。
例子:查询emp表deptno列相同的组的人数和deptno列,且组内人数不小于5.

select count(*), deptno from emp
 where count(*) >=5 group by deptno; 
 // 因为where先执行,这时候还没有分组,不知道个数,错误
select count(*), deptno from emp 
group by deptno having count(*)>=5;

order by 排序条件
排序条件:列名 升降序 如果升降序关键字省略,默认是asc
升序-> 由小到大 asc
降序-> 由大到小 desc
例子:查询hero表中的每一列,按power降序排列

select * from hero order by power desc;

多列排序: 排序条件1, 排序条件2 …
先按照条件1排序,条件1中取值相同的,再按照条件2排序
limit 限制个数
限制返回结果个数

limit m;    // 最多返回m个结果
limit n,m;  
// 最多返回m个结果,n代表起始下标,下标从0开始

经常用来实现分页应用,假设每页10条

第一页 limit 0,10;
第二页 limit 10,10;
第三页 limit 20,10;

消除取值重复的行
两个本来并不完全相同的元组在投影到指定的某些列上后,可能会变成相同的行,可以用DISTINCT消除它们。
查询学生学号

    SELECT DISTINCT Sno FROM SC;

单表查询

现有一学生表

+------+-------+------------+------+
| sid  | sname | birthday   | sex  |
+------+-------+------------+------+
| 1001 | 张三  | 1990-10-10 | 男   |
| 1002 | 李四  | 1981-10-10 | 男   |
| 1003 | 王五  | 1981-11-10 | 女   |
| 1004 | 赵六  | 1988-10-10 | 男   |
| 1005 | 孙七  | 1989-01-10 | 女   |
| 1006 | 周八  | 1990-10-10 | 男   |
| 1007 | 张三  | 1990-06-10 | 女   |
+------+-------+------------+------+

例子:
查询同名同姓学生名单,并统计同名人数

select count(*),name from student 
group by name having(count(*)>1);

连接查询

定义
若一个查询同时涉及两个以上的表,则称之为连接查询。连接查询是关系数据库中最主要的查询,包括等值连接查询、自然连接查询、非等值连接查询、自身连接查询、外连接查询和复合条件连接查询等。
1.等值连接查询与非等值连接查询
连接查询的where子句中用来连接两个表的条件称为连接条件或连接谓词,其一般格式为:

表名 列名 比较运算符 表名2 列名2
比较运算符主要有=、>=、<=、!=、>、< 等

当连接谓词为=时,称为等值连接。使用其他运算符为非等值连接。
连接谓词中的列名称为连接字段。连接条件中的各连接字段类型必须是可比的,但名字不必相同。
例子:查询所有同学的学号、姓名、选课数、总成绩

select student.sid,name,count(*),sum(score)
from student,sc 
where student.sid=sc.sid group by sid;

嵌套循环连接算法的基本思想:首先在表Student 中找到第一个元组,然后从头开始扫描SC表,逐查找与Student第一个元组的Sno相等的SC元组,找到后就将Student 中的第个元组与该元组拼接起来, 形成结果表中一个元组。SC全部查找完后,再找Student中第二个元组,然后再从头开始扫描SC.连一查找满足连接条件的元组,找到后就将Studemt 中的第二个元组与该元组拼接起来,形成结果表中个元组,重复上述操作,直到Sudent 中的全部元组都处理完毕为止
关系数据库管理系统执行该连接操作时用到了嵌套循环连接算法的基本思想。例中,如果在SC表上建立了索引的话,就不用每次全表扫描SC表了,而是根据Sno值通过索引找到相应的SC元组。用索引查询SC中满足条件的元组一般会比全表扫描快。若在等值连接中把目标列重复的属性列去掉则为自然连接。一条SQL语句可以同时完成选择和连接查询,这是WHERE子句是由连接谓词和选择谓词组成的复合条件。
2.自身连接
定义
连接不仅可以在两个表之间进行,也可以是一个表与其自己进行连接,称为表的自身连接。
例子:
查询每一门课的间接先修课(即先修课的先修课)
分析:在Course表中只有每门课的直接先修课信息,要满足目的,需要将Course表与其自身连接。为此,要为Course表取两个别名,一个是FIRST,另一个是SECOND。

SELECT FIRST.Cno,SECOND.Cpno
  FROM Course FIRST,Course SECOND
  WHERE FIRST.Cpno=SECOND.Cno;

3.外连接
左外连接 表1 left outer join 表2 on 连接条件
右外连接 表1 right outer join 表2 on 连接条件
其中outer可以省略
4.多表连接
连接操作出了可以是两表连接、自身连接外,还可以是两个以上的表进行连接,后者通常称为多表连接
关系数据库管理系统在执行多表连接时,通常先进行两个表的连接操作,再将其结果与第三个表进行连接。

嵌套查询

定义
在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。将一个查询块嵌套在另一个查询块的WHERE子句 或HAVING短语的条件中的查询称为嵌套查询。
不相关子查询
子查询的查询条件不依赖于父查询。
相关子查询
子查询的查询条件依赖于父查询。
带有IN谓词的子查询
例子:
查询与“刘晨”在同一个系学习的学生。
分析:此查询要求可以分步来完成
①确定“刘晨”所在系名

SELECT Sdept FROM Student WHERE Sname= ' 刘晨 ';  

② 查找所有在CS系学习的学生。

SELECT Sno, Sname, Sdept  FROM Student 
WHERE   Sdept= ' CS '

③替换

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

此查询为不相关子查询。
带有比较运算符的子查询
例子:
找出每个学生超过他选修课程平均成绩的课程号

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

带有ANY或ALL谓词的子查询
使用ANY或ALL谓词时必须同时使用比较运算 语义为:

> ANY 大于子查询结果中的某个值
> ALL 大于子查询结果中的所有值
< ANY 小于子查询结果中的某个值
< ALL 小于子查询结果中的所有值
>= ANY 大于等于子查询结果中的某个值
>= ALL 大于等于子查询结果中的所有值

例子
查询列Sdept中列值为CS的比列值不为CS的任意一个 学生年龄小的学生姓名和年龄

SELECT Sname,Sage FROM Student   
WHERE Sage < ANY (SELECT Sage  FROM Studnet 
WHERE Sdept= ' CS ') AND Sdept <> ‘CS ' ;  

带有EXISTS谓词的子查询
EXISTS谓词
带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true” 或逻辑假值“false”。
*若内层查询结果非空,则外层的WHERE子句返回真值
*若内层查询结果为空,则外层的WHERE子句返回假值
NOT EXISTS谓词
*若内层查询结果非空,则外层的WHERE子句返回假值
*若内层查询结果为空,则外层的WHERE子句返回真值
注意:由EXISTS引出的子查询,其目标列表达式通常都用 * ,因为带 EXISTS的子查询只返回真值或假值,给出列名无实际意义。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值