3.4.2-5 连接、嵌套、集合查询以及基于派生表的查询

第三章完整版->有道云笔记

  • 连接查询

等值与非等值连接查询

连接查询的WHERE子句用来连接两个表的条件称为连接条件连接谓词,一般格式为:

    [<表名1>.] <列名 1><比较运算符> [<表名2>.] <列名 2>

连接运算符为=时,称为等值连接。使用其他运算符称为非等值连接
连接谓词中的列名称为连接字段。连接条件中的各连接字段类型必须是可比的,但名字不必相同。

    /* 查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
       Sname是唯一的,可省略表名前缀,而Sno必须加上表名前缀,避免混淆 */
    SELECT Student.Sno, Sname
    FROM Student, SC
    WHERE Student.Sno = SC.Sno AND          /*  连接谓词 */
            SC.Cno = '2' AND SC.Grade > 90; /*  其他限定条件(选择谓词) */

自身连接

一个表与自己进行连接,要先为表取别名。

    /* 查询每一门课的间接先修课(即先修课的先修课) */
    SELECT FIRST.Cno, SECOND.Cpno
    FROM Course FIRST, Course SECOND
    WHERE FIRST.Cpno = SECOND.Cno;

FIRST表(Course表)

Cno Cname Cpno Ccredit
1 数据库 5 4
2 数学 2
3 信息系统 1 4
4 操作系统 6 3
5 数据结构 7 4
6 操作系统 2
7 数据结构 6 4

SECOND表(Course表)

Cno Cname Cpno Ccredit
1 数据库 5 4
2 数学 2
3 信息系统 1 4
4 操作系统 6 3
5 数据结构 7 4
6 操作系统 2
7 数据结构 6 4

连接结果:

Cno Cpno
1 7
3 5
5 6

外连接: [<表名1>] LEFT | RIGHT OUTER JOIN [<表名2>] ON 谓词

P55 2.4.2中详解:把悬浮元组也保存在结果关系中,而在其他属性上填空值(NULL)。保留左边关系所有元组为左外连接,保留右边关系中所有元组为右外连接。

例:左外连接,列出每个学生的基本情况及选课情况,若某个学生无选课,SC表属性上填NULL。

    SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade
    FROM Student LEFT OUTER JOIN SC ON(Student.Sno = SC.Sno);

多表连接

两个以上的表进行连接。

    /* 查询每个学生的学号、姓名、选修的课程名及成绩 */
    SELECT Student.Sno, Sname, Cname, Grade
    From Student, SC, Course
    WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno;
  • 嵌套查询

一个SELECT-FROM-WHERE语句称为一个查询块,将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询。上层查询块称为外层查询父查询,下层查询块称为内层查询子查询。子查询的SELECT语句中不能使用ORDER BY子句,ORDER BY子句只能对最终查询结果排序。

带有IN谓词的子查询(最常用)

    /* 查询与“刘晨”在同一个系学习的学生
       方法一:嵌套查询-不相关查询
       子查询的查询条件不依赖于父查询,称为不相关子查询 */
    SELECT Sno, Sname, Sdept 
    FROM Student 
    WHERE Sdept IN    /* 内查询结果的是一个值,可以用 = 代替IN */
            (SELECT Sdept
            FROM Student
            WHERE Sname = '刘晨');
    /* 方法二:自身连接 */
    SELECT S1.Sno, S1.Sname, S1.Sdept
    FROM Student S1, Student S2
    WHERE S1.Sdept = S2.Sdept AND S2.Sname = '刘晨'; 

[注]:有些嵌套查询可以用连接运算替代,尽可能采用连接运算

带有比较运算符的子查询

    // 找出每个学生超过他自己选修课程平均成绩的课程号
    // 子查询的查询条件依赖于父查询,称为相关子查询
    SELECT Sno, Cno
    FROM SC x
    WHERE Grade >= (SELECT AVG(Grade)  // 根据x.Sno求出某学生课程的平均成绩
                    FROM SC y
                    WHERE y.Sno = x.Sno);

带有ANY(SOME)或ALL谓词的子查询

子查询返回多值时,要用ANY或ALL谓词修饰符。

比较运算符+谓词 语义
>ANY 大于子查询结果中的某个值
>ALL 大于子查询结果中的所有值
<ANY 小于子查询结果中的某个值
<ALL 小于子查询结果中的所有值
>=ANY 大于等于子查询结果中的某个值
<=ALL 大于等于子查询结果中的所有值
<=ANY 小于等于子查询结果中的某个值
<=ALL 小于等于子查旬结果中的所有值
=ANY 等于子查询结果中的某个值
=ALL 等于子查询结果中的所有值(通常没有实际意义)
!=(或<>)ANY 不等于子查询结果中的某个值
!=(或<>)ALL 不等于子查询结果中的任何一个值
    <!--查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄-->
    SELECT Sname, Sage
    FROM Student
    WHERE Sage <ANY (SELECT Sage 
                    FROM Student 
                    WHERE Sdept = 'CS')
    AND Sdept <> 'CS';

带有EXISTS谓词的子查询

EXISTS代表存在量词,带有EXISTS谓词的子查询不返回任何数据,且产生逻辑真值“true”或逻辑价值“false”。
由EXISTS引出的子查询,其目标列表达式通常都用*

 /* 查询选修了全部课程的学生姓名 */
    SELECT Sname
    FROM Student
    WHERE NOT EXISTS
        (SELECT *
          FROM Course
          WHERE NOT EXISTS
              (SELECT *
                FROM SC
                WHERE Sno = Student.Sno 
                AND Cno = Course.Cno));

[注]:SQL中没有全称量词,但可以把带有全称量词的谓词转换为等价的带有存在量词的谓词,双重否定=>肯定。

  • 集合查询

SELECT语句查询的结果是元组的集合,所以多个SELECT语句的结果可进行集合查询。包括并操作UNION交操作INTERSECT差操作EXCEPT

   /* 查询计算机科学系的学生与年龄不大于19岁的学生的交集 */
   SELECT *
   FROM Student
   WHERE Sdept = 'CS'
   INTERSECT
   SELECT *
   FROM Student
   WHERE Sage <= 19;

[注]:参加集合操作的各查询结果列数、对应项的数据类型必须相同。

  • 基于派生表的查询

子查询也可以出现在FROM子句中,此时子查询生成的临时派生表成为主查询的查询对象。

    /* 找出每个学生超过他自己选修课程平均成绩的课程号 */
    SELECT Sno, Cno
    FROM SC, (SELECT Sno, Avg(Grade) FROM SC GROUP BY Sno)
             AS Avg_sc(avg_sno, avg_grade)
             WHERE SC.Sno = Avg_sc.sno AND SC.Grade >= Avg_sc.avg_grade;
  • SELECT语句的一般格式 P114
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • 1. SQL 简介 SQL 的目标 理想情况下,数据库语言应允许用户: 建立数据库和关系结构 完成基本数据管理任务...
    板蓝根plank阅读 2,327评论 0 11
  • 介绍多表查询等复杂SQL语句。 关系数据库的查询结果都是一个结果表(也是关系) 集聚函数 基本语法 统计元组个数C...
    zealscott阅读 823评论 0 0
  • 一、子查询定义 定义: 子查询允许把一个查询嵌套在另一个查询当中。 子查询,又叫内部查询,相对于内部查询,包含内部...
    我是强强阅读 3,152评论 0 4
  • SELECT:查询一个/多个/全部字段,也可以在列上做运算或链接,列别名和表别名。查询分为条件查询、排序查询、分组...
    TESTME阅读 980评论 0 2
  • 昨天晚上,公公婆婆叫我们去吃晚饭。中午的时候已经叫过,但女儿们不想出门,我自己有事,也就随着他们了。下午婆婆又给儿...
    隽嫕阅读 330评论 0 7