SQL之数据查询

SQL 92标准的数据查询语法格式:

SELECT [ALL | DISTINCT] <属性列表名>   /*如果没有指定DISTINCT短语,则默认为ALL,即保留结果中取
                                      值重复的行*/

FROM<表名或视图名> [,<表名或视图名>]...

[WHERE<条件表达式>]

[GROUP BY <列名>]

[HAVING <条件表达式>]

[ORDER BY <列名> [ASC | DESC] ];

SELECT类似于关系代数中的投影运算;WHERE子句的功能类似关系代数中的选择运算

GROUP将结果按照<列名> 旳值进行分组,该属性列名相等的分一组,每个组产生结果表中的一条记录,通常使用集函数,若带有HAVING短语,则结果只有满足条件的组才被选择出来。

ORDER BY 将查询的结果进行排序显示(ASC--升序;DESC--降序;默认升序)


  • SELECT子句中可以出现计算表达式
SELECT 学号,2019-出生年份

FROM 学生; 
  • 添加列别名
COLUMN AS <别名> 或者 <别名>
例:
  SELECT 学号,2019-出生年份 AS 年龄

  FROM 学生; 
常用查询条件
查询条件谓词
比较=、<>、>、<、>=、<=
算术运算+、-、*、/
确定范围BETWEEN AND,NOT BETWEEN AND
确定集合IN,NOT IN
字符匹配(模糊匹配)LIKE,NOT LIKE
空值IS NOLL,IS NOT NOLL
多重条件AND,OR

通配符:%代表任意长度;_代表任意单个字符

若要查询的字符本身含有%、_,此时需要借助ESCAPE'\'对通配符进行转义(如ABC_CNAME)

SELECT 学号,课程名

FROM SC;
WHERE 课程名 LIKE 'ABC\_CNAME' ESCAPE'\'
/*ESCAPE'\'表示‘\’为转码字符,则在‘\’后的‘_’不在具有通配符的含义*/ 

  


常用集函数
COUNT([DISTINCT|ALL] *)统计元组个数
COUNT([DISTINCT|ALL ] <列名>)统计一列中值的个数
SUM([DISTINCT|ALL ] <列名>)计算一列值的总和
AVG([DISTINCT|ALL ] <列名>)计算一列值的平均值
MAX([DISTINCT|ALL ] <列名>)求一列值中的最大值
MIN([DISTINCT|ALL ] <列名>)求一列值中的最小值
  • 连接查询

连接方法可分为theta方式和ANSI方式两种:

  使用WHERE条件连接的方法属于theta方式,要实现外部连接需要在字句中设置特殊字符+、*;

  使用JOIN关键字配合USING、ON等连接条件完成外部连接为ANSI方式;

外连接查询 

右外链接:规定所有记录都应该从链接语句右侧的表中返回。即使左侧的表中并没有匹配的记录,右表中该记录依然会返回,此时,左表的列将返回NULL值。

***内连接:只有满足连接条件的元组,即左右表中均有匹配的记录,才能作为结果返回***

SELECT sname,cno,grade
FROM S,SC
WHERE  SC.sno=(+)S.sno;--在等号左边(左外链接)--theta

SELECT sname,cno,grade
FROM S,SC
RIGHT OUTER JOIN C ON SC.sno=(+)S.sno;      --ANSI
  •  集合运算连接查询
运算符
UNION
INTERSECT
EXCEPT
均自动去除重复,若想保留在运算符后加ALL
(SELECT sno,cno,grade
FROM SC
WHERE  cno='011001')
EXCEPT
(SELECT sno,cno,grade
FROM SCsno,cno,grade
WHERE  cno='011002')--选修了011001号课程的学生中没有选修011002号课程的学生的sno,cno,grade
  • 嵌套查询

 由里向外依次处理

SELECT sname
FROM S
WHERE  sno IN
    (SELECT sno
     FROM SC
     WHERE  cno='011001');
/*SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询
需要注意:子查询SELECT语句中不能使用ORDER BY子句,ORDER BY语句只对最终查询结果排序*/

带有EXISTS谓词的子查询

EXISTS代表存在量词,带有EXISTS谓词的子查询不返回数据,只产生逻辑值true or false。

--查询选修了01001课程的学生学号和姓名

SELECT sname,sno
FROM S
WHERE EXISTS
    (SELECT *            --此处的目标列表达式通常用*,因为此处返回真假值,给出列名无实际意义
     FROM SC
     WHERE  S.sno=SC.sno
     AND SC.cno='01001');
/*执行顺序:
         从S表中依次取出每个元组的sno,用此值去检查SC表。
         若SC表存在这样的元组,其sno与此S.sno相等,并且该学生学习的课程号为01001.则取此学生的sno,sname送入结果表*/

几个典型的除法问题:

1.查询至少选修了001号学生选修的全部课程的学生学号

SELECT DISTINCT sno
FROM SC AS A
WHERE NOT EXISTS
    (SELECT *           
     FROM SC AS B
     WHERE  B.sno='001'
     AND NOT EXISTS
        (SELECT *
         FROM SC ASC
         WHERE A.sno=B.sno     
          AND B.cno=C.cno));

2.查询选修了全部课程的学生姓名

SELECT sname
FROM S
WHERE NOT EXISTS
    (SELECT *           
     FROM C 
     WHERE NOT EXISTS
        (SELECT *
         FROM SC
         WHERE sno=S.sno     
          AND cno=C.cno));

3.查询被所有学生都选修的课程名

SELECT cname
FROM C
WHERE NOT EXISTS
    (SELECT *           
     FROM S 
     WHERE NOT EXISTS
        (SELECT *
         FROM SC
         WHERE sno=S.sno     
          AND cno=C.cno));

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值