第 6 章  数据查询
SQL 的基本概念 SQL 包含 4 个部分: 数据定义语言 DDL(Data Definition Language )  数据查询语言 DQL(Data Query Language) 数据操纵语言 DML(Data Manipulation Language) 数据控制语言 DCL(Data Control Language)
数据定义 SQL  的数据定义功能包括:定义数据库、定义表、定义视图、定义索引。 定义数据库:  create database, drop database  定义表: create table, drop table ,alter table 定义视图: create view, drop view 定义索引: create index, drop index
使用 SELECT 语句实现单表查询、多表查询、嵌套查询、集合查询。 基本查询 嵌套查询 连接查询 查  询
查询 查询是数据库管理的核心操作。 SQL 语言提供了 select 语句进行数据库的查询。 Select 语句的一般格式: SELECT  [ALL|DISTINCT]< 目标列表达式 >...  FROM < 表名或视图名 >[,< 表名或视图名 >] ... [WHERE < 条件表达式 >]   [GROUP BY < 列名 1> [HAVING < 条件表达式 >]]   [ORDER BY < 列名 2> [ASC|DESC]]
SELECT 语句可以实现 : 选择 投影 Table 1 Table 2 Table 1 Table 1 连接
示例表 sno   sname  ssex  sage  sdept 06001  张三  男  20  IS 07012  李四  男  18  CS 06023  郭一  女  20  IS 05044  刘六  男  21  MA 07001  田七  女  18  MA 07020  丁五  男  19  CS Student 表
示例表 cno   cname  cpno  credit 1  数据库  5  4 高等数学  2  信息系统  1  4 4  操作系统  3 5  数据结构  2  4 6  C 语言  5  4  course 表 sno   cno   score 06001  1  93 06001  2  85 06001  3  77 06023  2  80 06023  3  91 06023  6  79 07012  4  92 07020  4  68 sc 表
1. 单表查询 SELECT  指明输出什么列 FROM  指明从哪个表查询 SELECT [DISTINCT] {*,  目标列表达式   [ 别名 ],...} FROM 表名 ; 基本的 SELECT  语句 :
选择全部列 sno  sname  ssex  sage  sdept --------- -------------- -----------  06001  张三  男  18  IS 07012  李四  男  18  CS …  …  …  …  … 07020  丁五  男  19  CS SELECT *   FROM  student;
选择指定的列 sno   sname --------- ------------- 06001  张三  07012  李四  …  …  07020  丁五  SELECT sno, sname FROM  student
例 : EMP 表
使用函数 SELECT sname, datediff(year,birthday,getdate()) FROM student; sname  无列名 ---------- --------- --------- 张三  29 李四  27 郭一  27 刘六  28 田七  27 丁五  29 ...
使用函数 SELECT sname, datediff(year,birthday,getdate()) AS sage FROM student; sname  sage ---------- --------- --------- 张三  29 李四  27 郭一  27 刘六  28 田七  27 丁五  29 ...
使用算术运算符 SELECT sno, cno, score,score+5 FROM sc; sno   cno   score  无列名 ---------- --------- --------- 06001  1  93  98 06001  2  85  90 06001  3  77  82 06023  2  80  85 06023  3  91  96 06023  6  79  84 ...
定义列的别名 SELECT ename AS name, sal salary FROM  emp; NAME  SALARY ------------- --------- ... SELECT ename &quot;Name&quot;, sal*12 &quot;Annual Salary&quot; FROM  emp; Name  Annual Salary ------------- ------------- ...
使用字符连接运算符 SELECT  sno + sname AS “ 学生” FROM  student; 学生 ------------------- 06001  张三 07012  李四 06023  郭一 05044  刘六 07001  田七 07020  丁五 ... SQL Server2000 使用‘ +’ 进行字符连接运算 ORACLE 使用‘ ||’ 进行字符连接运算
使用字符连接运算符 SELECT  rtrim( sno )  + sname AS “ 学生” FROM  student; 学生 ------------------- 06001 张三 07012 李四 06023 郭一 05044 刘六 07001 田七 07020 丁五 ... SQL Server2000 使用‘ +’ 进行字符连接运算 ORACLE 使用‘ ||’ 进行字符连接运算
使用字符连接运算符 Employee Details ------------------------- KING is a PRESIDENT BLAKE is a MANAGER CLARK is a MANAGER JONES is a MANAGER MARTIN is a SALESMAN ... 14 rows selected. SELECT ename +‘  ‘+ ‘ is a ’ +’ ‘+job    AS &quot;Employee Details&quot; FROM  emp;
消除重复行 默认情况下的选择操作产生了重复行 SELECT sdept FROM  student WHERE sdept=‘CS’; sdept --------- CS CS ...
消除重复行 使用 DISTINCT 参数消除重复行 SELECT DISTINCT sdept FROM  student WHERE sdept=‘CS’; sdept --------- CS ...
练习 : 如何对 SQL Server2000 的实例数据库 Northwind 实现以下查询 : 1 :查询所有订单的详细信息 2 :查询所有订单的订购日期 Select  *  from orders Select orderid,orderdate  from orders
练习 : 3 :查询所有订单的订购日期及预计的交货日期(假定通常交货期为 30 天) Select orderid,orderdate,orderdate+30  from orders Select orderid,orderdate,’ 预计的发货日期’ ,  orderdate+30 from orders Select orderid,orderdate+30 as  预计的发货日期    from orders
选择表中的若干元组 消除取值重复的行 查询满足条件的元组 关于比较运算符的使用 关于确定范围的使用 关于确定集合的使用 关于匹配的使用 关于空值的判断 关于逻辑运算符的判断
用于查询的条件表达式使用的运算符 NOT, AND, OR 逻辑运算符 IS NULL, IS NOT NULL 空值判断 LIKE, NOT LIKE 字符匹配 IN , NOT IN  确定集合 [NOT] BETWEEN…AND… 确定范围 = 、 > 、 < 、 >= 、 <= 、 <> 、 != 、 !> 、 !< 比较运算符
使用 SELECT 语句实现选择操作 “… 选取出 DEPTNO 为 10 的所有雇员 &quot; EMP EMPNO  ENAME  JOB  ...  DEPTNO  7839 KING PRESIDENT   10 7698 BLAKE MANAGER   30 7782 CLARK MANAGER   10 7566 JONES MANAGER   20 ... EMP EMPNO  ENAME  JOB  ...  DEPTNO  7839 KING PRESIDENT   10 7782 CLARK MANAGER   10 7934 MILLER CLERK   10
使用 WHERE 子句来选取元组 SELECT [DISTINCT] {*,  目标列表达式 [ 别名 ], ...} FROM  表名 [WHERE 条件表达式 ]; WHERE 短句跟在 FROM 短句的后面 WHERE 短句中可以使用运算符,包括:关系运算符、逻辑运算符及一些特殊的运算符。
使用 WHERE 子句来选取元组 SELECT ename, job, deptno FROM  emp WHERE  job='CLERK'; ENAME  JOB  DEPTNO ---------- --------- --------- JAMES  CLERK  30 SMITH  CLERK  20 ADAMS  CLERK  20 MILLER  CLERK  10
使用 where 子句示例 select sname from student where sdept=‘CS’ select sname,sage from student where sage<20  (where not sage>=20) select distinct sno from sc where score<60 丁五 李四 sname 19 丁五 18 田七 18 李四 sage sname sno
使用比较运算符 SELECT ename, sal, comm FROM  emp WHERE  sal<=comm; ENAME  SAL  COMM ---------- --------- --------- MARTIN  1250  1400
使用  BETWEEN  运算符 ENAME  SAL ---------- --------- MARTIN  1250 TURNER  1500 WARD  1250 ADAMS  1100 MILLER  1300 SELECT ename, sal FROM  emp WHERE sal BETWEEN 1000 AND 1500; Lower limit Higher limit
使用  IN  运算符 SELECT empno, ename, sal, mgr FROM  emp WHERE mgr IN (7902, 7566, 7788); EMPNO ENAME  SAL  MGR --------- ---------- --------- --------- 7902 FORD  3000  7566 7369 SMITH  800  7902 7788 SCOTT  3000  7566 7876 ADAMS  1100  7788
使用  IN  运算符 select sname,ssex from student where sdept in (‘CS’,’IS’,’MA’) select sname,ssex from student where sdept not in (‘CS’,’IS’,’MA’) … … 男 张三 男 丁五 女 田七 男 李四 ssex sname ssex sname
使用  LIKE  运算符 使用  LIKE  运算符可以进行字符串的匹配 . %  代表任意长度(或长度为 0 )的字符串 _  代表任意单个字符 匹配格式: [NOT] LIKE ‘< 匹配串 >’ [escape < 换码字符 >] SELECT ename FROM  emp WHERE ename LIKE 'S%';
使用  LIKE  运算符 找出 05 级学生信息 select sname,sage from student where sno like ’05%’ 找出所有姓‘李’的同学的姓名,性别 select sname,ssex from student where sname like ’ 李 %’ 找出姓‘丁’的单名学生的学号、姓名 select sno,sname from student where sname like ’ 丁 _’
使用  LIKE  运算符 找出第二个汉字为‘思’的学生学号、姓名 select sno,sname from student where sname like ’_ 思 %’ 找出不姓‘刘’的学生学号、姓名 select sno,sname from student where sname not like ’ 刘 %’
使用  LIKE  运算符 找出课程名为“ DB_Design” 的课号和学分 select cno,ccredit from sc where cname like ’DB\_Design’ escape ‘\’ 找出课程名为“ DB_” 开头并且倒数第三个字符为“ i” 的课程信息 select * from sc where cname like ’DB\_%i__’ escape ‘\’
使用  ESCAPE  进行转义后,可以查找 “ %” 或“ _” 。 使用  LIKE  运算符 SELECT ename FROM emp WHERE ename LIKE '_A%'; ENAME ----------  JAMES  WARD SELECT ename FROM emp WHERE ename LIKE '\_A%' escape ‘\’;
使用  IS NULL  运算符 检测是否为空( NULL )值 SELECT  ename, mgr FROM  emp WHERE  mgr IS NULL; ENAME  MGR ---------- --------- KING
使用  IS NULL  运算符 找出选修课成绩尚未登记的学生学号及其选修课程号 select sno,cno from sc where score is NULL 找出已经登记了选修课成绩的学生学号及其选修课程号 select sno,cno from sc where score is NOT NULL
使用  AND  运算符 SELECT empno, ename, job, sal FROM  emp WHERE  sal>=1100 AND  job='CLERK'; EMPNO ENAME  JOB  SAL --------- ---------- --------- --------- 7876 ADAMS  CLERK  1100 7934 MILLER  CLERK  1300
使用  OR  运算符 SELECT empno, ename, job, sal FROM  emp WHERE  sal>=1100 OR  job='CLERK'; EMPNO ENAME  JOB  SAL --------- ---------- --------- --------- 7839 KING  PRESIDENT  5000 7698 BLAKE  MANAGER  2850 7782 CLARK  MANAGER  2450 7566 JONES  MANAGER  2975 7654 MARTIN  SALESMAN  1250 ...
SELECT ename, job FROM  emp WHERE  job NOT IN ('CLERK','MANAGER','ANALYST'); ENAME  JOB ---------- --------- KING  PRESIDENT MARTIN  SALESMAN ALLEN  SALESMAN TURNER  SALESMAN WARD  SALESMAN 使用  NOT  运算符
优先顺序:比较运算符最优先,逻辑运算符中 NOT 优先级第一, AND 其次, OR 最后。 ENAME  JOB  SAL ---------- --------- --------- KING  PRESIDENT  5000 MARTIN  SALESMAN  1250 ALLEN  SALESMAN  1600 TURNER  SALESMAN  1500 WARD  SALESMAN  1250 SQL> SELECT ename, job, sal FROM  emp WHERE  job='SALESMAN' OR  job='PRESIDENT' AND  sal>1500;
可以使用括号来定义优先顺序。 ENAME  JOB  SAL ---------- --------- --------- KING  PRESIDENT  5000 ALLEN  SALESMAN  1600 SQL> SELECT  ename, job, sal FROM  emp WHERE  (job='SALESMAN' OR  job='PRESIDENT') AND  sal>1500;
IN  和  OR  的关系 关键字 in  相当于多个 or 的缩写形式,如 sdept in (‘CS’,’IS’,’MA’)  等价于 sdept=‘CS’ OR sdept=‘IS’ OR sdept=‘MA’
练习: 如何对 SQL Server2000 的实例数据库 Northwind 实现以下查询 : 6 :查询所有订单中已经交货的订单的详细信息 7 :查询所有国家为“ UK” 的客户的详细信息 Select  * from orders   where shippeddate<date() Select * from customers   where country=‘UK’
练习: 8 :查询所有单价在 20 到 25 元之间的产品名称和价格 9 :查询所有类别为 1 , 2 和 3 的产品的名称和价格 Select productname,unitprice from products  where unitprice between 20 and 25 Select productname,unitprice  from products  where categoryid in (1,2,3)
练习: 10 :查询所有以A开头的客户的详细信息 11 :查询所有客户名第三个字母为A的且国家为’ UK’ 的客户的详细信息 Select * from customers  where customerid like ‘A%’ Select * from customers where customerid like ‘_ _A%’ and country=‘UK’
ORDER BY  短语 使用  ORDER BY  短语来对查询结果排序以便更好地观察结果 ASC:  升序 ,  默认 DESC:  降序 注意: 如果元组中有空值存在,则在升序时,空值排在结果的最后;在降序时,空值排在结果的最前。
ORDER BY  短语 按照成绩由高到低(降序)对课程 4 的选修学生和成绩进行列示。 select sno,score from sc where cno=‘4’  order by score 92 07012 68 07020 score sno 68 07012 92 07020 score sno
ORDER BY  短语 使用  ORDER BY  短语来对查询结果排序 ASC:  升序 ,  默认 DESC:  降序 SELECT   ename, job, deptno, hiredate FROM   emp ORDER BY hiredate; ENAME  JOB  DEPTNO HIREDATE ---------- --------- --------- --------- SMITH  CLERK  20 17-DEC-80 ALLEN  SALESMAN  30 20-FEB-81 ...
按降序排列结果 SELECT   ename, job, deptno, hiredate FROM   emp ORDER BY hiredate DESC; ENAME  JOB  DEPTNO HIREDATE ---------- --------- --------- --------- ADAMS  CLERK  20 12-JAN-83 SCOTT  ANALYST  20 09-DEC-82 MILLER  CLERK  10 23-JAN-82 JAMES  CLERK  30 03-DEC-81 FORD  ANALYST  20 03-DEC-81 KING  PRESIDENT  10 17-NOV-81 MARTIN  SALESMAN  30 28-SEP-81 ...
按结果列的别名排序 SELECT  empno, ename, sal*12 annsal FROM  emp ORDER BY annsal; EMPNO ENAME  ANNSAL --------- ---------- --------- 7369 SMITH  9600 7900 JAMES  11400 7876 ADAMS  13200 7654 MARTIN  15000 7521 WARD  15000 7934 MILLER  15600 7844 TURNER  18000 ...
按多列排序 例、显示所有学生的信息,按系排序,同系中按年龄从大到小排序 Select * from student order by sdept,sage desc 在排序时可以指定多列,系统降按照指定列的顺序依次列示结果
按多列排序 SELECT  ename, deptno, sal FROM   emp ORDER BY  deptno, sal DESC; ENAME  DEPTNO  SAL ---------- --------- --------- KING  10  5000 CLARK  10  2450 MILLER  10  1300 FORD  20  3000 ...
使用集函数 又称集合函数、组函数、分组函数、聚集函数等,通过与分组短语一起使用,作用于元组集。 计算一列值的最小值 MIN([DISTINCT| ALL ] < 列名 >) 计算一列值的最大值 MAX([DISTINCT| ALL ] < 列名 >) 计算一列值的平均值 AVG([DISTINCT| ALL ] < 列名 >) 计算一列值的总和 SUM([DISTINCT| ALL ] < 列名 >) 统计一列中值的个数 COUNT([DISTINCT| ALL ] < 列名 >) 统计元组个数 COUNT([DISTINCT| ALL ] *)
使用集函数 集函数作用在一组元组上 EMP “ maximum  salary in  the EMP table” DEPTNO  SAL --------- --------- 10  2450 10  5000 10  1300 20  800 20  1100 20  3000 20  3000 20  2975 30  1600 30  2850 30  1250 30  950 30  1500 30  1250 MAX(SAL) --------- 5000
使用集函数 SELECT 目标列表达式 ,  集函数 ( 列名 ) FROM 表名 [WHERE 条件表达式 ] [ORDER BY 列名 ]; 常用集函数包括 : AVG  、 COUNT  、  MAX  、 MIN  、 SUM
AVG  和  SUM 适用于数值型数据  AVG(SAL)  MAX(SAL)  MIN(SAL)  SUM(SAL) -------- --------- --------- --------- 1400  1600  1250  5600 SELECT AVG(sal), MAX(sal), MIN(sal), SUM(sal) FROM emp WHERE job LIKE 'SALES%';
MIN  和  MAX  适用于不同类型的数据 SELECT MIN(hiredate), MAX(hiredate) FROM emp ; MIN(HIRED MAX(HIRED --------- --------- 17-DEC-80 12-JAN-83
COUNT  函数用于计数 COUNT(*) --------- 6 SELECT COUNT(*) FROM emp WHERE deptno = 30; SELECT COUNT(comm) FROM emp WHERE deptno = 30; COUNT(COMM) ----------- 4 忽略 NULL 值
示例 例、求总的学生数 SELECT COUNT(*) FROM student 例、求选修了课程的学生数 SELECT COUNT(DISTINCT sno) FROM sc 例、求课程 4 的平均成绩 SELECT AVG(score) FROM sc  WHERE cno=‘4’ 例、求课程 4 的最高成绩 SELECT MAX(score) FROM sc  WHERE cno=‘4’ 6 COUNT(*) 4 COUNT(DISTINCT sno) 80 AVG(score) 92 MAX(score)
创建数据分组 将查询结果表的各行按一列或多列取值相等的原则进行分组,目的是细化集合函数的作用对象。如果不分组,集合函数的作用对象就是整个结果,如果分组,集合函数的作用对象就是每一组。
创建数据分组  EMP “ EMP 表中每一部门的平均工资” DEPTNO  SAL --------- --------- 10  2450 10  5000 10  1300 20  800 20  1100 20  3000 20  3000 20  2975 30  1600 30  2850 30  1250 30  950 30  1500 30  1250 DEPTNO  AVG(SAL) ------- --------- 10 2916.6667 20  2175 30 1566.6667 2916.6667 2175 1566.6667
GROUP BY  短语 SELECT 目标列表达式 ,  集函数 ( 列名 ) FROM 表名 [WHERE 条件表达式 ] [GROUP BY 分组条件表达式 ] [ORDER BY 列名 ]; GROUP BY  子句将元组的集合分成了小组。
使用  GROUP BY  短语  GROUP BY  后的列不一定在 SELECT 中输出, SELECT  AVG(sal) FROM  emp GROUP BY deptno; AVG(SAL) ---------  2916.6667 2175 1566.6667
使用  GROUP BY  短语 SELECT 后的列除非使用了集函数,否则必须包括在 GROUP BY 短语中 SELECT  deptno, AVG(sal) FROM  emp GROUP BY deptno; DEPTNO  AVG(SAL) --------- --------- 10 2916.6667 20  2175 30 1566.6667
SELECT  deptno, job, sum(sal) FROM  emp GROUP BY deptno, job; DEPTNO JOB  SUM(SAL) --------- --------- --------- 10 CLERK  1300 10 MANAGER  2450 10 PRESIDENT  5000 20 ANALYST  6000 20 CLERK  1900 ... 9 rows selected. 按多列分组
按多列分组 EMP “ EMP 表中不同部门不同职位的工资总和” DEPTNO JOB  SAL --------- --------- --------- 10 MANAGER  2450 10 PRESIDENT  5000 10 CLERK  1300 20 CLERK  800 20 CLERK  1100 20 ANALYST  3000 20 ANALYST  3000 20 MANAGER  2975 30 SALESMAN  1600 30 MANAGER  2850 30 SALESMAN  1250 30 CLERK  950 30 SALESMAN  1500 30 SALESMAN  1250 JOB  SUM(SAL) --------- --------- CLERK  1300 MANAGER  2450 PRESIDENT  5000 ANALYST  6000 CLERK  1900 MANAGER  2975 CLERK  950 MANAGER  2850 SALESMAN  5600 DEPTNO -------- 10 10 10 20 20 20 30 30 30
示例 例、求每门课程的选修人数 SELECT cno,COUNT(sno) FROM sc  GROUP BY cno 例、查询选修人数超过 2 人(不含 2 人)的课程号 SELECT cno FROM sc GROUP BY cno HAVING COUNT(sno) >2 2 2 2 3 2 4 1 1 1 6 COUNT(sno) cno cno
对分组的结果进行筛选 “ 每一部门最高工资大于 $2900” EMP DEPTNO  SAL --------- --------- 10  2450 10  5000 10  1300 20  800 20  1100 20  3000 20  3000 20  2975 30  1600 30  2850 30  1250 30  950 30  1500 30  1250 DEPTNO  MAX(SAL) --------- --------- 10  5000 20  3000 5000 3000 2850
HAVING  短语 使用  HAVING  短语对分组结果进行筛选 HAVING 短语专门作用于分组,选择满足条件的分组 WHERE 短语作用于整个基本表,选择满足条件的元组,不能用于选择分组。 SELECT 目标列表达式 ,  集函数 FROM 表名 [WHERE 条件表达式 ] [GROUP BY 分组条件表达式 ] [HAVING 条件表达式 ] [ORDER BY 列名 ];
使用 HAVING  短语 SELECT  deptno, max(sal) FROM  emp GROUP BY deptno HAVING  max(sal)>2900; DEPTNO  MAX(SAL) --------- --------- 10  5000 20  3000
使用 HAVING  短语 SELECT  job, SUM(sal) PAYROLL FROM  emp WHERE   job NOT LIKE 'SALES%' GROUP BY  job HAVING  SUM(sal)>5000 ORDER BY  SUM(sal); JOB  PAYROLL --------- --------- ANALYST  6000 MANAGER  8275
嵌套的集函数 SELECT  max(avg(sal)) 2  FROM  emp 3  GROUP BY deptno; MAX(AVG(SAL)) ------------- 2916.6667
练习: 12 :查询客户名以 A 开头的客户在 1996 年发出的所有订单,按订单号排序输出 13 :查询每个供应商供应的所有产品的平均价格 Select * from orders  where customerid like ‘A%’ and  year(orderdate)=1996  order by orderid Select supplierid,avg(unitprice)  from products group by supllierid
WHERE 和  HAVING 同样是用于条件设置,但 WHERE 的作用体现在分组之前,而 HAVING 的作用体现在分组之后。 HAVING 子句不能单独使用,只能与 GROUP BY  子句配合使用。 WHERE 子句中不能使用集函数。
2. 嵌套查询 在 SQL 语言中,一个 select-from-where 语句称为一个查询块。 一个查询块嵌套在另一个查询块的 where 子句或 having 短语 中,称为嵌套查询。 嵌套查询使我们可以使用多个简单查询来构造复杂查询。
嵌套查询 例、查询选修了课程 2 的学生姓名。 SELECT sname FROM student  WHERE sno IN  (SELECT sno FROM sc WHERE cno=‘2’)  把括号外的查询块称为主查询(父查询),括号内的查询块称为子查询,嵌套查询的求解方法是 从里向外 的处理,每一个子查询在其上一层查询处理之前求解,查询结果作为建立其父查询的查找条件。
嵌套分类 带有 IN 谓词的子查询 带有比较运算符的子查询 带有 ANY 或 ALL 的子查询 带有 EXISTS 谓词的子查询
带有 IN 谓词的子查询 例、查询与“田七”在同一个系的学生。 SELECT sno,sname,sdept FROM student  WHERE sdept IN  (SELECT sdept FROM student WHERE sname=‘ 田七’ )  有时候为了区别主查询和子查询中出现的相同表名,可以为各查询中的表名定义不同的别名。
多层嵌套 例、查询选修了课程“信息系统”的学生学号和姓名。 SELECT sno,sname FROM student  WHERE sno IN  (SELECT sno FROM sc  WHERE cno IN (SELECT cno FROM course  WHERE cname=‘ 信息系统’ )) 子查询的查询条件不依赖于父查询,称为不相关子查询
带有比较运算符的子查询 当确切知道内层查询返回的是单值时,可以用比较运算符 例、查询选修了课程“信息系统”的学生学号和姓名。 SELECT sno,sname FROM student  WHERE sno IN  (SELECT sno FROM sc  WHERE cno = (SELECT cno FROM course  WHERE cname=‘ 信息系统’ ))
使用嵌套解决问题 “ 谁的工资比  Jones  高 ?” “ 哪一个雇员的工资比  Jones  高 ?” 主查询 ? “ Jones  的工资是多少 ?” ? 子查询
嵌套查询的实现 SELECT ename FROM  emp WHERE  sal >    (SELECT sal FROM  emp WHERE  empno=7566); ENAME ---------- KING FORD SCOTT 2975
嵌套查询的实现 ENAME  JOB ---------- --------- MILLER  CLERK SELECT  ename, job   FROM  emp WHERE  job =  (SELECT  job     FROM  emp     WHERE  empno = 7369) AND  sal >  (SELECT  sal FROM emp WHERE empno = 7876);  CLERK 1100
HAVING  短语中使用嵌套查询 SELECT deptno, MIN(sal) FROM emp GROUP BY deptno HAVING MIN(sal) > (SELECT MIN(sal) FROM emp WHERE deptno = 20); DEPTNO  MIN(SAL) ---------- ---------- 10  1300 30  950 800
以下两个查询结果一样吗 ? SELECT ename, deptno, sal, comm FROM emp WHERE  (sal, comm) IN (SELECT sal, comm   FROM  emp   WHERE  deptno = 30); SELECT  ename, deptno, sal, comm FROM  emp WHERE  sal IN  (SELECT sal FROM  emp WHERE  deptno = 30) AND comm IN  (SELECT comm FROM  emp WHERE  deptno = 30);
带有 ANY 或 ALL 的子查询 子查询返回单值时可以用比较运算符,而使用 ANY 或 ALL 谓词时则必须同时使用比较运算符 大于等于 ( 小于等于 ) 子查询中的所有值 >=(<=)ALL 等于 ( 不等于 ) 子查询中的所有值 =(!=)ALL 大于 ( 小于 ) 子查询中的所有值 >(<)ALL 等于 ( 不等于 ) 子查询中某个值 =(!=)ANY 大于等于 ( 小于等于 ) 子查询中某个值 >=(<=)ANY 大于 ( 小于 ) 子查询中某个值 >(<)ANY
示例 例、查询其他系中比 IS 系某一学生年龄小的学生名单。 SELECT sname,sage FROM student  WHERE sage < ANY (SELECT sage FROM student  WHERE sdept =‘IS’) AND sdept <>‘IS’ ORDER BY sage DESC
示例 也可以用集合函数实现 SELECT sname,sage FROM student  WHERE sage < (SELECT MAX(sage) FROM student  WHERE sdept =‘IS’) AND sdept <>‘IS’ ORDER BY sage DESC
示例 例、查询其他系中比 IS 系所有学生年龄都小的学生名单。 SELECT sname,sage FROM student  WHERE sage < ALL (SELECT sage FROM student  WHERE sdept =‘IS’) AND sdept <>‘IS’ ORDER BY sage DESC
示例 也可以用集合函数实现 SELECT sname,sage FROM student  WHERE sage < (SELECT MIN(sage) FROM student  WHERE sdept =‘IS’) AND sdept <>‘IS’ ORDER BY sage DESC
ANY 、 ALL 与集函数、 IN 的等价转换关系 <all 小于子查询结果中的所有值 <any  小于子查询结果中的某个值 >= MAX >MAX <= MIN <MIN NOT IN ALL >= MIN >MIN <= MAX <MAX IN ANY >= > <= < <> =
使用 ANY 运算符 EMPNO ENAME  JOB --------- ---------- --------- 7654 MARTIN  SALESMAN  7521 WARD  SALESMAN  SELECT  empno, ename, job FROM  emp WHERE  sal < ANY  (SELECT sal FROM emp WHERE job = 'CLERK') AND   job <> 'CLERK'; 950 800 1100 1300
使用 ALL 运算符 EMPNO ENAME  JOB --------- ---------- --------- 7839 KING  PRESIDENT 7566 JONES  MANAGER 7902 FORD  ANALYST 7788 SCOTT  ANALYST SQL> SELECT  empno, ename, job FROM  emp WHERE  sal > ALL    (SELECT avg(sal) FROM emp GROUP BY deptno); 2916.6667 2175 1566.6667
练习 : 1 :查询单价在 10 以下的产品的订购数量 select productid,quantity  from &quot;order details&quot;  where productid in (Select productid  from products  where unitprice<10)
练习 : 例 2 :查询比 2 类产品中任一产品价格低的所有产品的订购情况:  select  productid,quantity  from &quot;order details&quot;  where  unitprice <all  (Select unitprice from products  where categoryid=2)
带有 EXISTS 谓词的子查询 带 exists 的子查询不返回任何数据,只产生逻辑真或逻辑假。 例、查询所有选修了 1 号课程的学生学号和姓名。 SELECT sno,sname FROM student  WHERE EXISTS (SELECT * FROM sc  WHERE sno = student.sno AND cno=‘1’)
子查询的查询条件来源于外层父查询的某个属性值,这类查询称为相关子查询。此时查询执行不按从里到外的顺序。 先取外层查询中的第一个元组,根据它与内层查询的相关属性值处理内层查询,若 WHERE 子句返回值为真,则将该元组放入结果表;然后检查外层查询的下一个元组,重复这一过程,直至外层查询的元组全部检索完毕。
EXISTS  短语 select productid,quantity  from  “order details“ where  exists (Select * from products    where  unitprice<10) 注: 带 exists 的子查询不返回任何数据,只产生逻辑真或逻辑假。
EXISTS  短语 子查询的查询条件来源于外层父查询的某个属性值,这类查询称为相关子查询。此时查询执行不按从里到外的顺序。 select productid,quantity  from &quot;order details“ where exists (Select productid from products  where  productid=&quot;order details&quot;.productid  and unitprice<10)
4.  集合查询 Select 语句的查询结果是元组的集合,可以进行集合操作。 Union 操作符可以将多个查询结果合并成单个结果集,自动去除重复行。 参加 Union 操作的各结果集必须: ① 列数相同、 ② 对应项数据类型相同。 标准 SQL 没有直接提供集合交操作和集合差操作,可以转换为其他方法来实现。
集合查询 (2) Select productid  from products where unitprice<10 Union Select productid  from &quot;order details&quot;  where quantity>20
3. 多表查询 又称连接查询,其特点是在查询中使用了连接操作。 等值与非等值连接查询 自身连接 外连接 复合条件连接
连接查询 ( 涉及多个表的查询 ) EMPNO  DEPTNO  LOC ----- ------- --------  7839  10 NEW YORK 7698    30 CHICAGO 7782  10 NEW YORK 7566  20 DALLAS 7654    30 CHICAGO 7499  30 CHICAGO ... 14 rows selected. EMP  DEPT  EMPNO ENAME ... DEPTNO ------ ----- ... ------   7839 KING ...   10 7698 BLAKE ...   30 ... 7934 MILLER ...   10 DEPTNO DNAME  LOC  ------ ---------- -------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
用 SELECT 语句实现连接操作 使用 WHERE  短句来说明连接条件 当比较运算符使用‘ =’ 时,称为等值连接;使用其它运算符则称为非等值连接。 连接条件中的列名称为连接字段,其数据类型必须是可比的 SELECT 表名 1. 目标列  ,  表名 2. 目标列 FROM 表名 1,  表名 2 WHERE 表名 1. 列  < 比较运算符 >  表名 2.  列 ; WHERE 表名 1. 列  <BETWEEN>  表名 2.  列  AND 表名 3.  列   ;
等值连接 例、查询每个学生及其选修课程的情况 SELECT student.*,sc.* FROM student,sc  WHERE student.sno=sc.sno
等值连接 EMP  DEPT  EMPNO ENAME  DEPTNO ------ ------- ------- 7839 KING  10 7698 BLAKE  30 7782 CLARK  10 7566 JONES  20 7654 MARTIN  30 7499 ALLEN  30 7844 TURNER  30 7900 JAMES  30 7521 WARD  30 7902 FORD  20 7369 SMITH  20 ... 14 rows selected. DEPTNO DNAME  LOC  ------- ---------- -------- 10 ACCOUNTING NEW YORK 30 SALES   CHICAGO 10 ACCOUNTING NEW YORK  20 RESEARCH DALLAS 30 SALES   CHICAGO 30 SALES   CHICAGO 30 SALES   CHICAGO 30 SALES   CHICAGO 30 SALES   CHICAGO 20 RESEARCH DALLAS 20 RESEARCH DALLAS ... 14 rows selected. Foreign key Primary key
等值连接的实现 SELECT  emp.empno, emp.ename, emp.deptno,   dept.deptno, dept.loc FROM  emp, dept WHERE  emp.deptno=dept.deptno; EMPNO ENAME  DEPTNO DEPTNO LOC ----- ------ ------ ------ --------- 7839 KING   10  10 NEW YORK 7698 BLAKE    30  30 CHICAGO 7782 CLARK   10  10 NEW YORK 7566 JONES  20  20 DALLAS ... 14 rows selected.
使用表的别名简化工作 SELECT emp.empno, emp.ename, emp.deptno,    dept.deptno, dept.loc FROM  emp, dept WHERE  emp.deptno=dept.deptno; SELECT e.empno, e.ename, e.deptno,  d.deptno, d.loc FROM  emp e, dept d WHERE  e.deptno=d.deptno;
非等值连接 EMP SALGRADE EMPNO ENAME  SAL ------ ------- ------ 7839 KING  5000 7698 BLAKE  2850 7782 CLARK  2450 7566 JONES  2975 7654 MARTIN  1250 7499 ALLEN  1600 7844 TURNER  1500 7900 JAMES  950 ... 14 rows selected. GRADE  LOSAL  HISAL ----- ----- ------ 1  700 1200 2  1201 1400 3  1401 2000 4 2001 3000 5  3001 9999 “ EMP 表中的工资数额在 SALGRADE 表的 LOSAL 和 HISAL 之间”
非等值连接的实现 ENAME  SAL  GRADE ---------- --------- --------- JAMES  950  1 SMITH  800  1 ADAMS  1100  1 ... 14 rows selected. SELECT  e.ename, e.sal, s.grade FROM emp e, salgrade s WHERE  e.sal BETWEEN  s.losal AND s.hisal;
笛卡尔积: ENAME  DNAME ------  ---------- KING ACCOUNTING BLAKE   ACCOUNTING  ... KING RESEARCH BLAKE   RESEARCH ... 56 rows selected. EMP (14 rows)  EMPNO ENAME ... DEPTNO ------ ----- ... ------   7839 KING ...   10 7698 BLAKE ...   30 ... 7934 MILLER ...   10 WHERE  短句省略或无效时,表与表进行笛卡尔积运算。 DEPT (4 rows)  DEPTNO DNAME  LOC  ------ ---------- -------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON “ Cartesian product:  14*4=56 rows”
自身连接 连接操作不仅可以在两个表之间进行,也可以是一个表与其自己进行连接,称为自身连接。 例、查询每门课的间接先修课 ( 即先修课的先修课 ) 。 SELECT first.cno,second.cpno  FROM course first,course second  WHERE first.cpno=second.cno 5 3 5 2 6 2 1 second.cpno first.cno
自身连接 EMP (WORKER) EMP (MANAGER) EMPNO ENAME  MGR ----- ------ ----  7839 KING 7698 BLAKE 7839 7782 CLARK 7839 7566 JONES 7839 7654 MARTIN 7698 7499 ALLEN 7698 EMPNO ENAME ----- -------- 7839 KING 7839 KING 7839 KING 7698 BLAKE 7698 BLAKE “ 表中的雇员之间存在上下级关系 &quot;
自身连接的实现 WORKER.ENAME||'WORKSFOR'||MANAG ------------------------------- BLAKE works for KING CLARK works for KING JONES works for KING MARTIN works for BLAKE ... 13 rows selected. SELECT worker.ename+' works for ‘+manager.ename FROM  emp worker, emp manager WHERE  worker.mgr = manager.empno;
两个以上的表的连接 NAME CUSTID ----------- ------ JOCKSPORTS   100 TKB SPORT SHOP   101 VOLLYRITE   102 JUST TENNIS   103 K+T SPORTS   105 SHAPE UP   106 WOMENS SPORTS  107 ... ... 9 rows selected. CUSTOMER  CUSTID  ORDID ------- ------- 101  610 102  611 104  612 106  601 102  602 106  604 106  605 ...  21 rows selected. ORD  ORDID  ITEMID ------ ------- 610  3 611  1 612  1 601  1 602  1 ... 64 rows selected.  ITEM
外连接 在通常的连接操作中,只有满足连接条件的元组才出现在结果集中。但有时候也希望一些不满足连接条件的元组也作为输出。 外连接又可以分为左外连接 (left outer join) 、右外连接 (right outer join) 、全外连接 (full outer join) 。
外连接 EMP  DEPT  ENAME DEPTNO ----- ------ KING 10 BLAKE 30 CLARK 10 JONES 20 ... DEPTNO DNAME ------ ---------- 10  ACCOUNTING 30  SALES 10  ACCOUNTING 20 RESEARCH ... 40 OPERATIONS 没有雇员在 OPERATIONS 部门
SQL Server 中的外连接 外连接使用不同的标识说明: LEFT OUTER JOIN RIGHT OUTER JOIN FULL OUTER JOIN SELECT 表名 1. 目标列  ,  表名 2. 目标列 FROM 表 1 <left outer join /right outer join /full outer join> 表 2 ON 表名 1.  列  =  表名 2.  列 ;
示例 关系 Loan: 关系 Borrow: Perryridge Redwood Downtown Bname 1700 4000 3000 amount L-230 Smith L-230 L-155 Mary L-260 L-170 Jones L-170 Loanno custna Loanno
示例 Loan inner join Borrow on Loan.Loanno=Borrow.Loanno Redwood Downtown Bname 4000 3000 amount L-230 Smith L-230 L-170 Jones L-170 Loanno custna Loanno
示例 Loan natural inner join Borrow on Loan.Loanno=Borrow.Loanno Redwood Downtown Bname 4000 3000 amount Smith L-230 Jones L-170 custna Loanno
示例 Loan left outer join Borrow on Loan.Loanno=Borrow.Loanno NULL NULL 1700 Perryridge L-260 L-230 Smith 4000 Redwood L-230 Downtown Bname 3000 amount L-170 Jones L-170 Loanno custna Loanno
示例 Loan natural right outer join Borrow  on Loan.Loanno=Borrow.Loanno Mary NULL NULL L-155 Smith 4000 Redwood L-230 Downtown Bname 3000 amount Jones L-170 custna Loanno
示例 Loan full outer join Borrow  on Loan.Loanno=Borrow.Loanno NULL 1700 Perryridge L-260 Mary NULL NULL L-155 Smith 4000 Redwood L-230 Downtown Bname 3000 amount Jones L-170 custna Loanno
复合条件连接 当 WHERE 子句中出现多个条件的连接操作时,称为复合条件连接。 例、查询选修了 2 号课程且成绩在 90 分以上的学生。 SELECT student.sno,sname  FROM student,sc  WHERE student.sno=sc.sno AND sc.cno=‘2’ AND sc.score>90
复合条件连接 例、查询每个学生选修的课程名称及其成绩。 SELECT student.sno,sname,course.cname,sc.score  FROM student,sc,course  WHERE student.sno=sc.sno AND sc.cno=course.cno
练习: 1 :查询所有产品的详细分类信息 Select  categories.*,products.* from  categories,products  where  categories.categoryid=products.categoryid
练习: 2 :查询所有以 A 开始的客户的订单信息 , 内容包括:客户名,公司名称,订单号,订单日期,  Select orders.customerid, companyname,orderid,orderdate  from  customers,orders  where  customers.customerid=orders.customerid  and orders.customerid like “A%”
练习: 3 :查询每一个员工的上级,显示其员工号 select  first.employeeid,second.employeeid  from  employees first,employees second  where first.reportsto=second.employeeid select  first.employeeid,second.employeeid  from  employees first inner join employees second  On  first.reportsto=second.employeeid
练习: 4 : 查询所有订单的订单号和客户的公司名称 select  orders.orderid,customers.companyname from  orders,customers  where orders.customerid=customers.customerid 或: select orders.orderid,customers.companyname from orders inner join customers   on  orders.customerid=customers.customerid
连接查询 (8) 5 :查询“ order details” 表中 orderid 为 10248 的所有产品的产品号、产品名、类别名 Select  order details.productid,  products.productname,categories.categoryname  from  &quot;order details“ inner join products  on &quot;order details&quot;.productid=products.productid  inner join categories  on products.categoryid=categories.categoryid Where “order details”.orderid=‘10248’
实训: 实验 4  数据查询

第6章 数据查询

  • 1.
    第 6 章 数据查询
  • 2.
    SQL 的基本概念 SQL包含 4 个部分: 数据定义语言 DDL(Data Definition Language ) 数据查询语言 DQL(Data Query Language) 数据操纵语言 DML(Data Manipulation Language) 数据控制语言 DCL(Data Control Language)
  • 3.
    数据定义 SQL 的数据定义功能包括:定义数据库、定义表、定义视图、定义索引。 定义数据库: create database, drop database 定义表: create table, drop table ,alter table 定义视图: create view, drop view 定义索引: create index, drop index
  • 4.
  • 5.
    查询 查询是数据库管理的核心操作。 SQL语言提供了 select 语句进行数据库的查询。 Select 语句的一般格式: SELECT [ALL|DISTINCT]< 目标列表达式 >... FROM < 表名或视图名 >[,< 表名或视图名 >] ... [WHERE < 条件表达式 >] [GROUP BY < 列名 1> [HAVING < 条件表达式 >]] [ORDER BY < 列名 2> [ASC|DESC]]
  • 6.
    SELECT 语句可以实现 :选择 投影 Table 1 Table 2 Table 1 Table 1 连接
  • 7.
    示例表 sno sname ssex sage sdept 06001 张三 男 20 IS 07012 李四 男 18 CS 06023 郭一 女 20 IS 05044 刘六 男 21 MA 07001 田七 女 18 MA 07020 丁五 男 19 CS Student 表
  • 8.
    示例表 cno cname cpno credit 1 数据库 5 4 高等数学 2 信息系统 1 4 4 操作系统 3 5 数据结构 2 4 6 C 语言 5 4 course 表 sno cno score 06001 1 93 06001 2 85 06001 3 77 06023 2 80 06023 3 91 06023 6 79 07012 4 92 07020 4 68 sc 表
  • 9.
    1. 单表查询 SELECT 指明输出什么列 FROM 指明从哪个表查询 SELECT [DISTINCT] {*, 目标列表达式 [ 别名 ],...} FROM 表名 ; 基本的 SELECT 语句 :
  • 10.
    选择全部列 sno sname ssex sage sdept --------- -------------- ----------- 06001 张三 男 18 IS 07012 李四 男 18 CS … … … … … 07020 丁五 男 19 CS SELECT * FROM student;
  • 11.
    选择指定的列 sno sname --------- ------------- 06001 张三 07012 李四 … … 07020 丁五 SELECT sno, sname FROM student
  • 12.
  • 13.
    使用函数 SELECT sname,datediff(year,birthday,getdate()) FROM student; sname 无列名 ---------- --------- --------- 张三 29 李四 27 郭一 27 刘六 28 田七 27 丁五 29 ...
  • 14.
    使用函数 SELECT sname,datediff(year,birthday,getdate()) AS sage FROM student; sname sage ---------- --------- --------- 张三 29 李四 27 郭一 27 刘六 28 田七 27 丁五 29 ...
  • 15.
    使用算术运算符 SELECT sno,cno, score,score+5 FROM sc; sno cno score 无列名 ---------- --------- --------- 06001 1 93 98 06001 2 85 90 06001 3 77 82 06023 2 80 85 06023 3 91 96 06023 6 79 84 ...
  • 16.
    定义列的别名 SELECT enameAS name, sal salary FROM emp; NAME SALARY ------------- --------- ... SELECT ename &quot;Name&quot;, sal*12 &quot;Annual Salary&quot; FROM emp; Name Annual Salary ------------- ------------- ...
  • 17.
    使用字符连接运算符 SELECT sno + sname AS “ 学生” FROM student; 学生 ------------------- 06001 张三 07012 李四 06023 郭一 05044 刘六 07001 田七 07020 丁五 ... SQL Server2000 使用‘ +’ 进行字符连接运算 ORACLE 使用‘ ||’ 进行字符连接运算
  • 18.
    使用字符连接运算符 SELECT rtrim( sno ) + sname AS “ 学生” FROM student; 学生 ------------------- 06001 张三 07012 李四 06023 郭一 05044 刘六 07001 田七 07020 丁五 ... SQL Server2000 使用‘ +’ 进行字符连接运算 ORACLE 使用‘ ||’ 进行字符连接运算
  • 19.
    使用字符连接运算符 Employee Details------------------------- KING is a PRESIDENT BLAKE is a MANAGER CLARK is a MANAGER JONES is a MANAGER MARTIN is a SALESMAN ... 14 rows selected. SELECT ename +‘ ‘+ ‘ is a ’ +’ ‘+job AS &quot;Employee Details&quot; FROM emp;
  • 20.
    消除重复行 默认情况下的选择操作产生了重复行 SELECTsdept FROM student WHERE sdept=‘CS’; sdept --------- CS CS ...
  • 21.
    消除重复行 使用 DISTINCT参数消除重复行 SELECT DISTINCT sdept FROM student WHERE sdept=‘CS’; sdept --------- CS ...
  • 22.
    练习 : 如何对SQL Server2000 的实例数据库 Northwind 实现以下查询 : 1 :查询所有订单的详细信息 2 :查询所有订单的订购日期 Select * from orders Select orderid,orderdate from orders
  • 23.
    练习 : 3:查询所有订单的订购日期及预计的交货日期(假定通常交货期为 30 天) Select orderid,orderdate,orderdate+30 from orders Select orderid,orderdate,’ 预计的发货日期’ , orderdate+30 from orders Select orderid,orderdate+30 as 预计的发货日期 from orders
  • 24.
    选择表中的若干元组 消除取值重复的行 查询满足条件的元组关于比较运算符的使用 关于确定范围的使用 关于确定集合的使用 关于匹配的使用 关于空值的判断 关于逻辑运算符的判断
  • 25.
    用于查询的条件表达式使用的运算符 NOT, AND,OR 逻辑运算符 IS NULL, IS NOT NULL 空值判断 LIKE, NOT LIKE 字符匹配 IN , NOT IN 确定集合 [NOT] BETWEEN…AND… 确定范围 = 、 > 、 < 、 >= 、 <= 、 <> 、 != 、 !> 、 !< 比较运算符
  • 26.
    使用 SELECT 语句实现选择操作“… 选取出 DEPTNO 为 10 的所有雇员 &quot; EMP EMPNO ENAME JOB ... DEPTNO 7839 KING PRESIDENT 10 7698 BLAKE MANAGER 30 7782 CLARK MANAGER 10 7566 JONES MANAGER 20 ... EMP EMPNO ENAME JOB ... DEPTNO 7839 KING PRESIDENT 10 7782 CLARK MANAGER 10 7934 MILLER CLERK 10
  • 27.
    使用 WHERE 子句来选取元组SELECT [DISTINCT] {*, 目标列表达式 [ 别名 ], ...} FROM 表名 [WHERE 条件表达式 ]; WHERE 短句跟在 FROM 短句的后面 WHERE 短句中可以使用运算符,包括:关系运算符、逻辑运算符及一些特殊的运算符。
  • 28.
    使用 WHERE 子句来选取元组SELECT ename, job, deptno FROM emp WHERE job='CLERK'; ENAME JOB DEPTNO ---------- --------- --------- JAMES CLERK 30 SMITH CLERK 20 ADAMS CLERK 20 MILLER CLERK 10
  • 29.
    使用 where 子句示例select sname from student where sdept=‘CS’ select sname,sage from student where sage<20 (where not sage>=20) select distinct sno from sc where score<60 丁五 李四 sname 19 丁五 18 田七 18 李四 sage sname sno
  • 30.
    使用比较运算符 SELECT ename,sal, comm FROM emp WHERE sal<=comm; ENAME SAL COMM ---------- --------- --------- MARTIN 1250 1400
  • 31.
    使用 BETWEEN 运算符 ENAME SAL ---------- --------- MARTIN 1250 TURNER 1500 WARD 1250 ADAMS 1100 MILLER 1300 SELECT ename, sal FROM emp WHERE sal BETWEEN 1000 AND 1500; Lower limit Higher limit
  • 32.
    使用 IN 运算符 SELECT empno, ename, sal, mgr FROM emp WHERE mgr IN (7902, 7566, 7788); EMPNO ENAME SAL MGR --------- ---------- --------- --------- 7902 FORD 3000 7566 7369 SMITH 800 7902 7788 SCOTT 3000 7566 7876 ADAMS 1100 7788
  • 33.
    使用 IN 运算符 select sname,ssex from student where sdept in (‘CS’,’IS’,’MA’) select sname,ssex from student where sdept not in (‘CS’,’IS’,’MA’) … … 男 张三 男 丁五 女 田七 男 李四 ssex sname ssex sname
  • 34.
    使用 LIKE 运算符 使用 LIKE 运算符可以进行字符串的匹配 . % 代表任意长度(或长度为 0 )的字符串 _ 代表任意单个字符 匹配格式: [NOT] LIKE ‘< 匹配串 >’ [escape < 换码字符 >] SELECT ename FROM emp WHERE ename LIKE 'S%';
  • 35.
    使用 LIKE 运算符 找出 05 级学生信息 select sname,sage from student where sno like ’05%’ 找出所有姓‘李’的同学的姓名,性别 select sname,ssex from student where sname like ’ 李 %’ 找出姓‘丁’的单名学生的学号、姓名 select sno,sname from student where sname like ’ 丁 _’
  • 36.
    使用 LIKE 运算符 找出第二个汉字为‘思’的学生学号、姓名 select sno,sname from student where sname like ’_ 思 %’ 找出不姓‘刘’的学生学号、姓名 select sno,sname from student where sname not like ’ 刘 %’
  • 37.
    使用 LIKE 运算符 找出课程名为“ DB_Design” 的课号和学分 select cno,ccredit from sc where cname like ’DB\_Design’ escape ‘\’ 找出课程名为“ DB_” 开头并且倒数第三个字符为“ i” 的课程信息 select * from sc where cname like ’DB\_%i__’ escape ‘\’
  • 38.
    使用 ESCAPE 进行转义后,可以查找 “ %” 或“ _” 。 使用 LIKE 运算符 SELECT ename FROM emp WHERE ename LIKE '_A%'; ENAME ---------- JAMES WARD SELECT ename FROM emp WHERE ename LIKE '\_A%' escape ‘\’;
  • 39.
    使用 ISNULL 运算符 检测是否为空( NULL )值 SELECT ename, mgr FROM emp WHERE mgr IS NULL; ENAME MGR ---------- --------- KING
  • 40.
    使用 ISNULL 运算符 找出选修课成绩尚未登记的学生学号及其选修课程号 select sno,cno from sc where score is NULL 找出已经登记了选修课成绩的学生学号及其选修课程号 select sno,cno from sc where score is NOT NULL
  • 41.
    使用 AND 运算符 SELECT empno, ename, job, sal FROM emp WHERE sal>=1100 AND job='CLERK'; EMPNO ENAME JOB SAL --------- ---------- --------- --------- 7876 ADAMS CLERK 1100 7934 MILLER CLERK 1300
  • 42.
    使用 OR 运算符 SELECT empno, ename, job, sal FROM emp WHERE sal>=1100 OR job='CLERK'; EMPNO ENAME JOB SAL --------- ---------- --------- --------- 7839 KING PRESIDENT 5000 7698 BLAKE MANAGER 2850 7782 CLARK MANAGER 2450 7566 JONES MANAGER 2975 7654 MARTIN SALESMAN 1250 ...
  • 43.
    SELECT ename, jobFROM emp WHERE job NOT IN ('CLERK','MANAGER','ANALYST'); ENAME JOB ---------- --------- KING PRESIDENT MARTIN SALESMAN ALLEN SALESMAN TURNER SALESMAN WARD SALESMAN 使用 NOT 运算符
  • 44.
    优先顺序:比较运算符最优先,逻辑运算符中 NOT 优先级第一,AND 其次, OR 最后。 ENAME JOB SAL ---------- --------- --------- KING PRESIDENT 5000 MARTIN SALESMAN 1250 ALLEN SALESMAN 1600 TURNER SALESMAN 1500 WARD SALESMAN 1250 SQL> SELECT ename, job, sal FROM emp WHERE job='SALESMAN' OR job='PRESIDENT' AND sal>1500;
  • 45.
    可以使用括号来定义优先顺序。 ENAME JOB SAL ---------- --------- --------- KING PRESIDENT 5000 ALLEN SALESMAN 1600 SQL> SELECT ename, job, sal FROM emp WHERE (job='SALESMAN' OR job='PRESIDENT') AND sal>1500;
  • 46.
    IN 和 OR 的关系 关键字 in 相当于多个 or 的缩写形式,如 sdept in (‘CS’,’IS’,’MA’) 等价于 sdept=‘CS’ OR sdept=‘IS’ OR sdept=‘MA’
  • 47.
    练习: 如何对 SQLServer2000 的实例数据库 Northwind 实现以下查询 : 6 :查询所有订单中已经交货的订单的详细信息 7 :查询所有国家为“ UK” 的客户的详细信息 Select * from orders where shippeddate<date() Select * from customers where country=‘UK’
  • 48.
    练习: 8 :查询所有单价在20 到 25 元之间的产品名称和价格 9 :查询所有类别为 1 , 2 和 3 的产品的名称和价格 Select productname,unitprice from products where unitprice between 20 and 25 Select productname,unitprice from products where categoryid in (1,2,3)
  • 49.
    练习: 10 :查询所有以A开头的客户的详细信息11 :查询所有客户名第三个字母为A的且国家为’ UK’ 的客户的详细信息 Select * from customers where customerid like ‘A%’ Select * from customers where customerid like ‘_ _A%’ and country=‘UK’
  • 50.
    ORDER BY 短语 使用 ORDER BY 短语来对查询结果排序以便更好地观察结果 ASC: 升序 , 默认 DESC: 降序 注意: 如果元组中有空值存在,则在升序时,空值排在结果的最后;在降序时,空值排在结果的最前。
  • 51.
    ORDER BY 短语 按照成绩由高到低(降序)对课程 4 的选修学生和成绩进行列示。 select sno,score from sc where cno=‘4’ order by score 92 07012 68 07020 score sno 68 07012 92 07020 score sno
  • 52.
    ORDER BY 短语 使用 ORDER BY 短语来对查询结果排序 ASC: 升序 , 默认 DESC: 降序 SELECT ename, job, deptno, hiredate FROM emp ORDER BY hiredate; ENAME JOB DEPTNO HIREDATE ---------- --------- --------- --------- SMITH CLERK 20 17-DEC-80 ALLEN SALESMAN 30 20-FEB-81 ...
  • 53.
    按降序排列结果 SELECT ename, job, deptno, hiredate FROM emp ORDER BY hiredate DESC; ENAME JOB DEPTNO HIREDATE ---------- --------- --------- --------- ADAMS CLERK 20 12-JAN-83 SCOTT ANALYST 20 09-DEC-82 MILLER CLERK 10 23-JAN-82 JAMES CLERK 30 03-DEC-81 FORD ANALYST 20 03-DEC-81 KING PRESIDENT 10 17-NOV-81 MARTIN SALESMAN 30 28-SEP-81 ...
  • 54.
    按结果列的别名排序 SELECT empno, ename, sal*12 annsal FROM emp ORDER BY annsal; EMPNO ENAME ANNSAL --------- ---------- --------- 7369 SMITH 9600 7900 JAMES 11400 7876 ADAMS 13200 7654 MARTIN 15000 7521 WARD 15000 7934 MILLER 15600 7844 TURNER 18000 ...
  • 55.
    按多列排序 例、显示所有学生的信息,按系排序,同系中按年龄从大到小排序 Select* from student order by sdept,sage desc 在排序时可以指定多列,系统降按照指定列的顺序依次列示结果
  • 56.
    按多列排序 SELECT ename, deptno, sal FROM emp ORDER BY deptno, sal DESC; ENAME DEPTNO SAL ---------- --------- --------- KING 10 5000 CLARK 10 2450 MILLER 10 1300 FORD 20 3000 ...
  • 57.
    使用集函数 又称集合函数、组函数、分组函数、聚集函数等,通过与分组短语一起使用,作用于元组集。 计算一列值的最小值MIN([DISTINCT| ALL ] < 列名 >) 计算一列值的最大值 MAX([DISTINCT| ALL ] < 列名 >) 计算一列值的平均值 AVG([DISTINCT| ALL ] < 列名 >) 计算一列值的总和 SUM([DISTINCT| ALL ] < 列名 >) 统计一列中值的个数 COUNT([DISTINCT| ALL ] < 列名 >) 统计元组个数 COUNT([DISTINCT| ALL ] *)
  • 58.
    使用集函数 集函数作用在一组元组上 EMP“ maximum salary in the EMP table” DEPTNO SAL --------- --------- 10 2450 10 5000 10 1300 20 800 20 1100 20 3000 20 3000 20 2975 30 1600 30 2850 30 1250 30 950 30 1500 30 1250 MAX(SAL) --------- 5000
  • 59.
    使用集函数 SELECT 目标列表达式, 集函数 ( 列名 ) FROM 表名 [WHERE 条件表达式 ] [ORDER BY 列名 ]; 常用集函数包括 : AVG 、 COUNT 、 MAX 、 MIN 、 SUM
  • 60.
    AVG 和 SUM 适用于数值型数据 AVG(SAL) MAX(SAL) MIN(SAL) SUM(SAL) -------- --------- --------- --------- 1400 1600 1250 5600 SELECT AVG(sal), MAX(sal), MIN(sal), SUM(sal) FROM emp WHERE job LIKE 'SALES%';
  • 61.
    MIN 和 MAX 适用于不同类型的数据 SELECT MIN(hiredate), MAX(hiredate) FROM emp ; MIN(HIRED MAX(HIRED --------- --------- 17-DEC-80 12-JAN-83
  • 62.
    COUNT 函数用于计数COUNT(*) --------- 6 SELECT COUNT(*) FROM emp WHERE deptno = 30; SELECT COUNT(comm) FROM emp WHERE deptno = 30; COUNT(COMM) ----------- 4 忽略 NULL 值
  • 63.
    示例 例、求总的学生数 SELECTCOUNT(*) FROM student 例、求选修了课程的学生数 SELECT COUNT(DISTINCT sno) FROM sc 例、求课程 4 的平均成绩 SELECT AVG(score) FROM sc WHERE cno=‘4’ 例、求课程 4 的最高成绩 SELECT MAX(score) FROM sc WHERE cno=‘4’ 6 COUNT(*) 4 COUNT(DISTINCT sno) 80 AVG(score) 92 MAX(score)
  • 64.
  • 65.
    创建数据分组 EMP“ EMP 表中每一部门的平均工资” DEPTNO SAL --------- --------- 10 2450 10 5000 10 1300 20 800 20 1100 20 3000 20 3000 20 2975 30 1600 30 2850 30 1250 30 950 30 1500 30 1250 DEPTNO AVG(SAL) ------- --------- 10 2916.6667 20 2175 30 1566.6667 2916.6667 2175 1566.6667
  • 66.
    GROUP BY 短语 SELECT 目标列表达式 , 集函数 ( 列名 ) FROM 表名 [WHERE 条件表达式 ] [GROUP BY 分组条件表达式 ] [ORDER BY 列名 ]; GROUP BY 子句将元组的集合分成了小组。
  • 67.
    使用 GROUPBY 短语 GROUP BY 后的列不一定在 SELECT 中输出, SELECT AVG(sal) FROM emp GROUP BY deptno; AVG(SAL) --------- 2916.6667 2175 1566.6667
  • 68.
    使用 GROUPBY 短语 SELECT 后的列除非使用了集函数,否则必须包括在 GROUP BY 短语中 SELECT deptno, AVG(sal) FROM emp GROUP BY deptno; DEPTNO AVG(SAL) --------- --------- 10 2916.6667 20 2175 30 1566.6667
  • 69.
    SELECT deptno,job, sum(sal) FROM emp GROUP BY deptno, job; DEPTNO JOB SUM(SAL) --------- --------- --------- 10 CLERK 1300 10 MANAGER 2450 10 PRESIDENT 5000 20 ANALYST 6000 20 CLERK 1900 ... 9 rows selected. 按多列分组
  • 70.
    按多列分组 EMP “EMP 表中不同部门不同职位的工资总和” DEPTNO JOB SAL --------- --------- --------- 10 MANAGER 2450 10 PRESIDENT 5000 10 CLERK 1300 20 CLERK 800 20 CLERK 1100 20 ANALYST 3000 20 ANALYST 3000 20 MANAGER 2975 30 SALESMAN 1600 30 MANAGER 2850 30 SALESMAN 1250 30 CLERK 950 30 SALESMAN 1500 30 SALESMAN 1250 JOB SUM(SAL) --------- --------- CLERK 1300 MANAGER 2450 PRESIDENT 5000 ANALYST 6000 CLERK 1900 MANAGER 2975 CLERK 950 MANAGER 2850 SALESMAN 5600 DEPTNO -------- 10 10 10 20 20 20 30 30 30
  • 71.
    示例 例、求每门课程的选修人数 SELECTcno,COUNT(sno) FROM sc GROUP BY cno 例、查询选修人数超过 2 人(不含 2 人)的课程号 SELECT cno FROM sc GROUP BY cno HAVING COUNT(sno) >2 2 2 2 3 2 4 1 1 1 6 COUNT(sno) cno cno
  • 72.
    对分组的结果进行筛选 “ 每一部门最高工资大于$2900” EMP DEPTNO SAL --------- --------- 10 2450 10 5000 10 1300 20 800 20 1100 20 3000 20 3000 20 2975 30 1600 30 2850 30 1250 30 950 30 1500 30 1250 DEPTNO MAX(SAL) --------- --------- 10 5000 20 3000 5000 3000 2850
  • 73.
    HAVING 短语使用 HAVING 短语对分组结果进行筛选 HAVING 短语专门作用于分组,选择满足条件的分组 WHERE 短语作用于整个基本表,选择满足条件的元组,不能用于选择分组。 SELECT 目标列表达式 , 集函数 FROM 表名 [WHERE 条件表达式 ] [GROUP BY 分组条件表达式 ] [HAVING 条件表达式 ] [ORDER BY 列名 ];
  • 74.
    使用 HAVING 短语 SELECT deptno, max(sal) FROM emp GROUP BY deptno HAVING max(sal)>2900; DEPTNO MAX(SAL) --------- --------- 10 5000 20 3000
  • 75.
    使用 HAVING 短语 SELECT job, SUM(sal) PAYROLL FROM emp WHERE job NOT LIKE 'SALES%' GROUP BY job HAVING SUM(sal)>5000 ORDER BY SUM(sal); JOB PAYROLL --------- --------- ANALYST 6000 MANAGER 8275
  • 76.
    嵌套的集函数 SELECT max(avg(sal)) 2 FROM emp 3 GROUP BY deptno; MAX(AVG(SAL)) ------------- 2916.6667
  • 77.
    练习: 12 :查询客户名以A 开头的客户在 1996 年发出的所有订单,按订单号排序输出 13 :查询每个供应商供应的所有产品的平均价格 Select * from orders where customerid like ‘A%’ and year(orderdate)=1996 order by orderid Select supplierid,avg(unitprice) from products group by supllierid
  • 78.
    WHERE 和 HAVING 同样是用于条件设置,但 WHERE 的作用体现在分组之前,而 HAVING 的作用体现在分组之后。 HAVING 子句不能单独使用,只能与 GROUP BY 子句配合使用。 WHERE 子句中不能使用集函数。
  • 79.
    2. 嵌套查询 在SQL 语言中,一个 select-from-where 语句称为一个查询块。 一个查询块嵌套在另一个查询块的 where 子句或 having 短语 中,称为嵌套查询。 嵌套查询使我们可以使用多个简单查询来构造复杂查询。
  • 80.
    嵌套查询 例、查询选修了课程 2的学生姓名。 SELECT sname FROM student WHERE sno IN (SELECT sno FROM sc WHERE cno=‘2’) 把括号外的查询块称为主查询(父查询),括号内的查询块称为子查询,嵌套查询的求解方法是 从里向外 的处理,每一个子查询在其上一层查询处理之前求解,查询结果作为建立其父查询的查找条件。
  • 81.
    嵌套分类 带有 IN谓词的子查询 带有比较运算符的子查询 带有 ANY 或 ALL 的子查询 带有 EXISTS 谓词的子查询
  • 82.
    带有 IN 谓词的子查询例、查询与“田七”在同一个系的学生。 SELECT sno,sname,sdept FROM student WHERE sdept IN (SELECT sdept FROM student WHERE sname=‘ 田七’ ) 有时候为了区别主查询和子查询中出现的相同表名,可以为各查询中的表名定义不同的别名。
  • 83.
    多层嵌套 例、查询选修了课程“信息系统”的学生学号和姓名。 SELECTsno,sname FROM student WHERE sno IN (SELECT sno FROM sc WHERE cno IN (SELECT cno FROM course WHERE cname=‘ 信息系统’ )) 子查询的查询条件不依赖于父查询,称为不相关子查询
  • 84.
    带有比较运算符的子查询 当确切知道内层查询返回的是单值时,可以用比较运算符 例、查询选修了课程“信息系统”的学生学号和姓名。SELECT sno,sname FROM student WHERE sno IN (SELECT sno FROM sc WHERE cno = (SELECT cno FROM course WHERE cname=‘ 信息系统’ ))
  • 85.
    使用嵌套解决问题 “ 谁的工资比 Jones 高 ?” “ 哪一个雇员的工资比 Jones 高 ?” 主查询 ? “ Jones 的工资是多少 ?” ? 子查询
  • 86.
    嵌套查询的实现 SELECT enameFROM emp WHERE sal > (SELECT sal FROM emp WHERE empno=7566); ENAME ---------- KING FORD SCOTT 2975
  • 87.
    嵌套查询的实现 ENAME JOB ---------- --------- MILLER CLERK SELECT ename, job FROM emp WHERE job = (SELECT job FROM emp WHERE empno = 7369) AND sal > (SELECT sal FROM emp WHERE empno = 7876); CLERK 1100
  • 88.
    HAVING 短语中使用嵌套查询SELECT deptno, MIN(sal) FROM emp GROUP BY deptno HAVING MIN(sal) > (SELECT MIN(sal) FROM emp WHERE deptno = 20); DEPTNO MIN(SAL) ---------- ---------- 10 1300 30 950 800
  • 89.
    以下两个查询结果一样吗 ? SELECTename, deptno, sal, comm FROM emp WHERE (sal, comm) IN (SELECT sal, comm FROM emp WHERE deptno = 30); SELECT ename, deptno, sal, comm FROM emp WHERE sal IN (SELECT sal FROM emp WHERE deptno = 30) AND comm IN (SELECT comm FROM emp WHERE deptno = 30);
  • 90.
    带有 ANY 或ALL 的子查询 子查询返回单值时可以用比较运算符,而使用 ANY 或 ALL 谓词时则必须同时使用比较运算符 大于等于 ( 小于等于 ) 子查询中的所有值 >=(<=)ALL 等于 ( 不等于 ) 子查询中的所有值 =(!=)ALL 大于 ( 小于 ) 子查询中的所有值 >(<)ALL 等于 ( 不等于 ) 子查询中某个值 =(!=)ANY 大于等于 ( 小于等于 ) 子查询中某个值 >=(<=)ANY 大于 ( 小于 ) 子查询中某个值 >(<)ANY
  • 91.
    示例 例、查询其他系中比 IS系某一学生年龄小的学生名单。 SELECT sname,sage FROM student WHERE sage < ANY (SELECT sage FROM student WHERE sdept =‘IS’) AND sdept <>‘IS’ ORDER BY sage DESC
  • 92.
    示例 也可以用集合函数实现 SELECTsname,sage FROM student WHERE sage < (SELECT MAX(sage) FROM student WHERE sdept =‘IS’) AND sdept <>‘IS’ ORDER BY sage DESC
  • 93.
    示例 例、查询其他系中比 IS系所有学生年龄都小的学生名单。 SELECT sname,sage FROM student WHERE sage < ALL (SELECT sage FROM student WHERE sdept =‘IS’) AND sdept <>‘IS’ ORDER BY sage DESC
  • 94.
    示例 也可以用集合函数实现 SELECTsname,sage FROM student WHERE sage < (SELECT MIN(sage) FROM student WHERE sdept =‘IS’) AND sdept <>‘IS’ ORDER BY sage DESC
  • 95.
    ANY 、 ALL与集函数、 IN 的等价转换关系 <all 小于子查询结果中的所有值 <any 小于子查询结果中的某个值 >= MAX >MAX <= MIN <MIN NOT IN ALL >= MIN >MIN <= MAX <MAX IN ANY >= > <= < <> =
  • 96.
    使用 ANY 运算符EMPNO ENAME JOB --------- ---------- --------- 7654 MARTIN SALESMAN 7521 WARD SALESMAN SELECT empno, ename, job FROM emp WHERE sal < ANY (SELECT sal FROM emp WHERE job = 'CLERK') AND job <> 'CLERK'; 950 800 1100 1300
  • 97.
    使用 ALL 运算符EMPNO ENAME JOB --------- ---------- --------- 7839 KING PRESIDENT 7566 JONES MANAGER 7902 FORD ANALYST 7788 SCOTT ANALYST SQL> SELECT empno, ename, job FROM emp WHERE sal > ALL (SELECT avg(sal) FROM emp GROUP BY deptno); 2916.6667 2175 1566.6667
  • 98.
    练习 : 1:查询单价在 10 以下的产品的订购数量 select productid,quantity from &quot;order details&quot; where productid in (Select productid from products where unitprice<10)
  • 99.
    练习 : 例2 :查询比 2 类产品中任一产品价格低的所有产品的订购情况: select productid,quantity from &quot;order details&quot; where unitprice <all (Select unitprice from products where categoryid=2)
  • 100.
    带有 EXISTS 谓词的子查询带 exists 的子查询不返回任何数据,只产生逻辑真或逻辑假。 例、查询所有选修了 1 号课程的学生学号和姓名。 SELECT sno,sname FROM student WHERE EXISTS (SELECT * FROM sc WHERE sno = student.sno AND cno=‘1’)
  • 101.
  • 102.
    EXISTS 短语select productid,quantity from “order details“ where exists (Select * from products where unitprice<10) 注: 带 exists 的子查询不返回任何数据,只产生逻辑真或逻辑假。
  • 103.
    EXISTS 短语子查询的查询条件来源于外层父查询的某个属性值,这类查询称为相关子查询。此时查询执行不按从里到外的顺序。 select productid,quantity from &quot;order details“ where exists (Select productid from products where productid=&quot;order details&quot;.productid and unitprice<10)
  • 104.
    4. 集合查询Select 语句的查询结果是元组的集合,可以进行集合操作。 Union 操作符可以将多个查询结果合并成单个结果集,自动去除重复行。 参加 Union 操作的各结果集必须: ① 列数相同、 ② 对应项数据类型相同。 标准 SQL 没有直接提供集合交操作和集合差操作,可以转换为其他方法来实现。
  • 105.
    集合查询 (2) Selectproductid from products where unitprice<10 Union Select productid from &quot;order details&quot; where quantity>20
  • 106.
    3. 多表查询 又称连接查询,其特点是在查询中使用了连接操作。等值与非等值连接查询 自身连接 外连接 复合条件连接
  • 107.
    连接查询 ( 涉及多个表的查询) EMPNO DEPTNO LOC ----- ------- -------- 7839 10 NEW YORK 7698 30 CHICAGO 7782 10 NEW YORK 7566 20 DALLAS 7654 30 CHICAGO 7499 30 CHICAGO ... 14 rows selected. EMP DEPT EMPNO ENAME ... DEPTNO ------ ----- ... ------ 7839 KING ... 10 7698 BLAKE ... 30 ... 7934 MILLER ... 10 DEPTNO DNAME LOC ------ ---------- -------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
  • 108.
    用 SELECT 语句实现连接操作使用 WHERE 短句来说明连接条件 当比较运算符使用‘ =’ 时,称为等值连接;使用其它运算符则称为非等值连接。 连接条件中的列名称为连接字段,其数据类型必须是可比的 SELECT 表名 1. 目标列 , 表名 2. 目标列 FROM 表名 1, 表名 2 WHERE 表名 1. 列 < 比较运算符 > 表名 2. 列 ; WHERE 表名 1. 列 <BETWEEN> 表名 2. 列 AND 表名 3. 列 ;
  • 109.
    等值连接 例、查询每个学生及其选修课程的情况 SELECTstudent.*,sc.* FROM student,sc WHERE student.sno=sc.sno
  • 110.
    等值连接 EMP DEPT EMPNO ENAME DEPTNO ------ ------- ------- 7839 KING 10 7698 BLAKE 30 7782 CLARK 10 7566 JONES 20 7654 MARTIN 30 7499 ALLEN 30 7844 TURNER 30 7900 JAMES 30 7521 WARD 30 7902 FORD 20 7369 SMITH 20 ... 14 rows selected. DEPTNO DNAME LOC ------- ---------- -------- 10 ACCOUNTING NEW YORK 30 SALES CHICAGO 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 30 SALES CHICAGO 30 SALES CHICAGO 30 SALES CHICAGO 30 SALES CHICAGO 20 RESEARCH DALLAS 20 RESEARCH DALLAS ... 14 rows selected. Foreign key Primary key
  • 111.
    等值连接的实现 SELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.loc FROM emp, dept WHERE emp.deptno=dept.deptno; EMPNO ENAME DEPTNO DEPTNO LOC ----- ------ ------ ------ --------- 7839 KING 10 10 NEW YORK 7698 BLAKE 30 30 CHICAGO 7782 CLARK 10 10 NEW YORK 7566 JONES 20 20 DALLAS ... 14 rows selected.
  • 112.
    使用表的别名简化工作 SELECT emp.empno,emp.ename, emp.deptno, dept.deptno, dept.loc FROM emp, dept WHERE emp.deptno=dept.deptno; SELECT e.empno, e.ename, e.deptno, d.deptno, d.loc FROM emp e, dept d WHERE e.deptno=d.deptno;
  • 113.
    非等值连接 EMP SALGRADEEMPNO ENAME SAL ------ ------- ------ 7839 KING 5000 7698 BLAKE 2850 7782 CLARK 2450 7566 JONES 2975 7654 MARTIN 1250 7499 ALLEN 1600 7844 TURNER 1500 7900 JAMES 950 ... 14 rows selected. GRADE LOSAL HISAL ----- ----- ------ 1 700 1200 2 1201 1400 3 1401 2000 4 2001 3000 5 3001 9999 “ EMP 表中的工资数额在 SALGRADE 表的 LOSAL 和 HISAL 之间”
  • 114.
    非等值连接的实现 ENAME SAL GRADE ---------- --------- --------- JAMES 950 1 SMITH 800 1 ADAMS 1100 1 ... 14 rows selected. SELECT e.ename, e.sal, s.grade FROM emp e, salgrade s WHERE e.sal BETWEEN s.losal AND s.hisal;
  • 115.
    笛卡尔积: ENAME DNAME ------ ---------- KING ACCOUNTING BLAKE ACCOUNTING ... KING RESEARCH BLAKE RESEARCH ... 56 rows selected. EMP (14 rows) EMPNO ENAME ... DEPTNO ------ ----- ... ------ 7839 KING ... 10 7698 BLAKE ... 30 ... 7934 MILLER ... 10 WHERE 短句省略或无效时,表与表进行笛卡尔积运算。 DEPT (4 rows) DEPTNO DNAME LOC ------ ---------- -------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON “ Cartesian product: 14*4=56 rows”
  • 116.
    自身连接 连接操作不仅可以在两个表之间进行,也可以是一个表与其自己进行连接,称为自身连接。 例、查询每门课的间接先修课( 即先修课的先修课 ) 。 SELECT first.cno,second.cpno FROM course first,course second WHERE first.cpno=second.cno 5 3 5 2 6 2 1 second.cpno first.cno
  • 117.
    自身连接 EMP (WORKER)EMP (MANAGER) EMPNO ENAME MGR ----- ------ ---- 7839 KING 7698 BLAKE 7839 7782 CLARK 7839 7566 JONES 7839 7654 MARTIN 7698 7499 ALLEN 7698 EMPNO ENAME ----- -------- 7839 KING 7839 KING 7839 KING 7698 BLAKE 7698 BLAKE “ 表中的雇员之间存在上下级关系 &quot;
  • 118.
    自身连接的实现 WORKER.ENAME||'WORKSFOR'||MANAG -------------------------------BLAKE works for KING CLARK works for KING JONES works for KING MARTIN works for BLAKE ... 13 rows selected. SELECT worker.ename+' works for ‘+manager.ename FROM emp worker, emp manager WHERE worker.mgr = manager.empno;
  • 119.
    两个以上的表的连接 NAME CUSTID----------- ------ JOCKSPORTS 100 TKB SPORT SHOP 101 VOLLYRITE 102 JUST TENNIS 103 K+T SPORTS 105 SHAPE UP 106 WOMENS SPORTS 107 ... ... 9 rows selected. CUSTOMER CUSTID ORDID ------- ------- 101 610 102 611 104 612 106 601 102 602 106 604 106 605 ... 21 rows selected. ORD ORDID ITEMID ------ ------- 610 3 611 1 612 1 601 1 602 1 ... 64 rows selected. ITEM
  • 120.
  • 121.
    外连接 EMP DEPT ENAME DEPTNO ----- ------ KING 10 BLAKE 30 CLARK 10 JONES 20 ... DEPTNO DNAME ------ ---------- 10 ACCOUNTING 30 SALES 10 ACCOUNTING 20 RESEARCH ... 40 OPERATIONS 没有雇员在 OPERATIONS 部门
  • 122.
    SQL Server 中的外连接外连接使用不同的标识说明: LEFT OUTER JOIN RIGHT OUTER JOIN FULL OUTER JOIN SELECT 表名 1. 目标列 , 表名 2. 目标列 FROM 表 1 <left outer join /right outer join /full outer join> 表 2 ON 表名 1. 列 = 表名 2. 列 ;
  • 123.
    示例 关系 Loan:关系 Borrow: Perryridge Redwood Downtown Bname 1700 4000 3000 amount L-230 Smith L-230 L-155 Mary L-260 L-170 Jones L-170 Loanno custna Loanno
  • 124.
    示例 Loan innerjoin Borrow on Loan.Loanno=Borrow.Loanno Redwood Downtown Bname 4000 3000 amount L-230 Smith L-230 L-170 Jones L-170 Loanno custna Loanno
  • 125.
    示例 Loan naturalinner join Borrow on Loan.Loanno=Borrow.Loanno Redwood Downtown Bname 4000 3000 amount Smith L-230 Jones L-170 custna Loanno
  • 126.
    示例 Loan leftouter join Borrow on Loan.Loanno=Borrow.Loanno NULL NULL 1700 Perryridge L-260 L-230 Smith 4000 Redwood L-230 Downtown Bname 3000 amount L-170 Jones L-170 Loanno custna Loanno
  • 127.
    示例 Loan naturalright outer join Borrow on Loan.Loanno=Borrow.Loanno Mary NULL NULL L-155 Smith 4000 Redwood L-230 Downtown Bname 3000 amount Jones L-170 custna Loanno
  • 128.
    示例 Loan fullouter join Borrow on Loan.Loanno=Borrow.Loanno NULL 1700 Perryridge L-260 Mary NULL NULL L-155 Smith 4000 Redwood L-230 Downtown Bname 3000 amount Jones L-170 custna Loanno
  • 129.
    复合条件连接 当 WHERE子句中出现多个条件的连接操作时,称为复合条件连接。 例、查询选修了 2 号课程且成绩在 90 分以上的学生。 SELECT student.sno,sname FROM student,sc WHERE student.sno=sc.sno AND sc.cno=‘2’ AND sc.score>90
  • 130.
    复合条件连接 例、查询每个学生选修的课程名称及其成绩。 SELECTstudent.sno,sname,course.cname,sc.score FROM student,sc,course WHERE student.sno=sc.sno AND sc.cno=course.cno
  • 131.
    练习: 1 :查询所有产品的详细分类信息Select categories.*,products.* from categories,products where categories.categoryid=products.categoryid
  • 132.
    练习: 2 :查询所有以A 开始的客户的订单信息 , 内容包括:客户名,公司名称,订单号,订单日期, Select orders.customerid, companyname,orderid,orderdate from customers,orders where customers.customerid=orders.customerid and orders.customerid like “A%”
  • 133.
    练习: 3 :查询每一个员工的上级,显示其员工号select first.employeeid,second.employeeid from employees first,employees second where first.reportsto=second.employeeid select first.employeeid,second.employeeid from employees first inner join employees second On first.reportsto=second.employeeid
  • 134.
    练习: 4 :查询所有订单的订单号和客户的公司名称 select orders.orderid,customers.companyname from orders,customers where orders.customerid=customers.customerid 或: select orders.orderid,customers.companyname from orders inner join customers on orders.customerid=customers.customerid
  • 135.
    连接查询 (8) 5:查询“ order details” 表中 orderid 为 10248 的所有产品的产品号、产品名、类别名 Select order details.productid, products.productname,categories.categoryname from &quot;order details“ inner join products on &quot;order details&quot;.productid=products.productid inner join categories on products.categoryid=categories.categoryid Where “order details”.orderid=‘10248’
  • 136.
    实训: 实验 4 数据查询