SQL之数据查询

SQL之数据查询

文章为个人读书总结笔记 发现错误以及如果有什么建议可以及时通知我哟!

SQL语言使用SELECT语句进行查询数据

  • 格式

    SELECT    [ALL|DISTINCT] 
    <目标表达式>
    [,<目标表达式>]
    ...
    FROM <表名或者视图名>
    [,<表名或者视图名>...] | (<SELECT语句>)[AS]<别名>
    [WHERE <条件表达式> ]
    [GROUP BY <列名1> [HAVING <条件表达式>]]
    [ORDER BY <列名2> [ASC|DESC]];
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 含义
      • 根据WHERE子句的条件表达式FROM子句指定的基本表或者视图找出满足条件元组
      • 再按SELECT子句罗列出的表达式选出元组中的属性值形成结果表
      • 如果有GROUP BY子句,将结果表<列名1>值进行划分组,值相同为一组
      • 如果GROUP BY子句带有HAVING条件短语,则以组为单位,选出满足条件的组
      • 如果有ORDERBY子句,将结果表按照<列名2>的值进行升序或者降序处理
        • ASC : 升序
        • DESC : 降序

假如我想:单表查询

实现:选择表中的若干列(SELECT

我能:查询指定列

  • 例子:查询表S的所有Sno, Sname

    SELECT Sno,Sname
    FROM S;
         
         
    • 1
    • 2
    • 执行过程
      • 从S表中取出一个元组
      • 选择元组的Sno, Sname的属性值形成一个新的元组作为输出
      • 对S表中的其他元组做同样的处理
      • 形成最终结果关系输出
  • 例子:查询S表中的所有Sname,Sno,Sdept

    SELECT    Sname,Sno,Sdept
    FROM S;
         
         
    • 1
    • 2
    • 注意:目标表达式中各个列的顺序可以与查询表中的顺序不同( 由用户自定义结果表

我能:查询全部列

  • 例子:查询全部S表的所有属性

    • 方法一 : 列出完整目标表达式
    SELECT Sno,Sname,Sdept,Sage
    FROM    S;
         
         
    • 1
    • 2
    • 方法二 : 使用 * 代替整个目标表达式
    SELECT  *
    FROM    S;
         
         
    • 1
    • 2

我能:查询经过计算后得到的值

  • 补充:目标表达式

    • 不仅可以是表中的属性列

    • 例子参照上面罗列出来的

    • 还可以是表达式 ( 例如针对整数的减法运算

    • 例子:查询S表的Sname,以及出生年份( 2018 - Sage

      SELECT    Sname,2018-Sage
      FROM  S;
             
             
      • 1
      • 2
    • 还可以是字符串常量

    • 例子:查询S表的Sname,添加字符串 “Year of Birth:’ 属性列,以及出生年份

      SELECT    Sname,'Year of Birth:',2018-Sage
      FROM  S;
             
             
      • 1
      • 2
    • 还可以是函数

    • 例子:查询S表中的Sdept,要求数据为小写

      SELECT    LOWER(Sdept)
      FROM  S;
             
             
      • 1
      • 2
  • 补充:为目标表达式指定别名

    • 例子:查询表S,结果表为表达式 2018-Sage 指定别名为BIRTHDAY

    • 影响:结果表中的属性列标题由2018-Sage 变成了 BIRTHDAY

    SELECT  2018-Sage BIRTHDAY, Sname
    FROM    S;
         
         
    • 1
    • 2

实现:选择表中的若干元组(WHERE

我能:消除取值重复的行(DISTANCT

  • 使用:DISTINCT

  • 例子:查询SC表中的Sno,消除重复的行

    SELECT    DISTANCT Sno
    FROM  SC;
         
         
    • 1
    • 2

我能:查询满足条件的元组(WHERE

  • 常用的查询条件 ( 条件表达式
查询条件 谓词
比较 [NOT] =,>,<,>=,<=,!=,<>,!>,!<
确定范围 [NOT] BETWEEN AND
确定集合 [NOT] IN
字符匹配 [NOT] LIKE
空值 IS [NOT] NULL
多重条件(逻辑运算) AND, OR, NOT
  • 比较大小

    • = :等于

    • > : 大于

    • < :小于

    • >= :大于等于

    • <= :小于等于

    • !=<> :不等于

    • !> :不大于

    • !<:不小于

    • 例子:查询S表中,满足Sdept=’CS’的所有元组,选择Sname输出

    SELECT  Sname
    FROM    S
    WHERE   Sdept='CS';
         
         
    • 1
    • 2
    • 3
  • 确定范围

    • BETWEEN 下限 AND 上限

    • NOT BETWEEN 下限 AND 上限

    • 例子:从S表中查询Sage在20~23之间的数据,输出Sname,Sage

    SELECT  Sname,Sage
    FROM    S
    WHERE   Sage BETWEEN 20 AND 23;
         
         
    • 1
    • 2
    • 3
  • 确定集合

    • IN : 给出域(集合),确定是否在域内

    • NOT IN

    • 例子:从S表中查询满足Sdept值在给定值域(‘CS’,’MA’,’IS’)内,输出Sname,Ssex

    SELECT  Sname,Ssex
    FROM    S
    WHERE   Sdept IN ('CS','MA','IS');
         
         
    • 1
    • 2
    • 3
  • 字符匹配

    • LIKE

    • NOT LIKE

    • 格式:

    [NOT]   LIKE  '<匹配串>' [ESCAPE '<换码字符>']
         
         
    • 1
    • 含义

      • 查找的元组的指定属性列值要满足与<匹配串>相匹配
    • 匹配串

      • 完整字符串
      • 含有通配符%_的字符串
      • %: 代表任意长度字符串( 甚至是0 ( 即空串
        • 例如:a%b 代表以a开头,以b结尾的所有字符串
        • acdb, acb, ab, …
      • _ :代表任意当个字符
        • 例如:a_b代表以a开头,以b结尾的长度为3的所有字符串
        • acb, adb, …
    • ESCAPE '<换码字符>'

      • 当匹配串本身就想含有通配符%或者_, 则需要转义

      • 例如:从C表中查询Cname为’DB_Design’的元组,输出Cno

      SELECT  Cno
      FROM    C
      WHERE   Cname LIKE 'DE\_Design' ESCAPE'\';
             
             
      • 1
      • 2
      • 3

    • 例子:从S表中查询Sno为’201215121’的元组,并输出全部信息

    SELECT *
    FROM    S
    WHERE   Sno LIKE '201215121';
    
    补充:不含通配符 LIKE 等价于 =
    
    SELECT *
    FROM    S
    WHERE   Sno = '201215121';
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 涉及空值的查询

    • IS NULL

    • 不能有 = 代替 IS

    • IS NOT NULL

    • 例子:查询SC表中Grade为空值的元组,输出Sno,Cno

    SELECT  Sno,Cno
    FROM    SC
    WHERE   Grade IS NULL;
         
         
    • 1
    • 2
    • 3
  • 多重条件查询

    • AND : 优先级高于 OR (注意短路

    • OR : IN实际上是多个OR的缩写

    • 例子:从S表中查询Sdept为CS,并且Sage< 20的元组,输出Sname

    SELECT  Sname
    FROM    S
    WHERE   Sdept='CS' AND  Sage<20;
         
         
    • 1
    • 2
    • 3

实现:ORDER BY 子句

  • 例子:从SC表中查询Cno为3的元组,结果表包含Sno,Grade,然后按照Grade降序输出

    SELECT    Sno,Grade
    FROM  SC
    WHERE Cno=3
    ORDER     BY  Grade DESC;
         
         
    • 1
    • 2
    • 3
    • 4
    • 注意:空值
    • 对于空值,排序时显示的次序由具体的系统来决定

使用:聚集函数

函数及格式 含义
COUNT(*) 统计元组个数
COUNT( [DISTANCT|ALL ] <列名>) 统计一列中值的个数
SUM( [DISTANCT|ALL ] <列名> ) 计算某一列值总和( 数值类型列)
AVG( [DISTANCT|ALL ] <列名>) 计算某一列值平均值( 数值类型列)
MAX( [DISTANCT|ALL ] <列名>) 求某一列的最大值
MIN( [DISTANCT|ALL ] <列名>) 求某一列的最小值

(注意:DISTANCT : 不重复(默认是ALL:可取重复值

  • 例子:查询S表的元组数目并输出

    SELECT    COUNT(*)
    FROM  S;
         
         
    • 1
    • 2
  • 注意:空值

  • 除了 COUNT(*)外的聚集函数跳过空值,处理非空值

  • 注意使用环境

  • 用于SELECT子句和GROUP BY(下目将会介绍)中的HAVING子句

  • 不能用于WHERE子句

实现:GROUP BY 子句

  • 分组的目的

    • 细化聚集函数的作用对象(分组后,聚集函数作用于组,有组则作用于组
  • 例子:从SC表中按Cno进行分组,然后输出Cno,以及COUNT(Sno)

    SELECT    Cno,COUNT(Sno)
    FROM  SC
    GROUP BY  Cno;
         
         
    • 1
    • 2
    • 3
    • 执行步骤
      • 从SC表选择元组
      • 按照Cno对元组进行分组
      • 输出分组后的Cno,输出分组后每组的COUNT(Sno)
  • 补充:对组的限制条件

    • HAVING子句

    • HAVINGWHERE的区别:作用对象不同

      • HAVING作用于分组
      • WHERE作用于基本表或视图
    • 例子:从SC表中选择元组,按Sno分组,选出组中的元组数目大于3的组别,输出Sno

      SELECT    Sno
      FROM  SC
      GROUP BY  Sno
      HAVING  COUNT(*)>3;
             
             
      • 1
      • 2
      • 3
      • 4

假如我想:连接查询( FROM

  • 定义:查询同时涉及两个以上的表
  • 地位:关系数据库中最主要的查询
  • 分类
    • 等值连接查询
    • 自然连接查询
    • 非等值连接查询
    • 自身连接查询
    • 外连接查询
    • 复合条件连接查询

实现:等值与非等值连接

连接两个表

  • 连接条件(连接谓词

    • 定义:WHERE子句连接两个表的条件部分
  • 关键子句:WHERE

  • 格式

    [<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2>
         
         
    • 1
    • 比较运算符:=,>, < , …

    • =等值连接

      • 去掉重复的等值连接:自然连接
    • 其他为非等值连接

    • 特殊:连接谓词

    • BETWEEN ... AND ...

    [<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>
         
         
    • 1
    • 连接字段
      • 定义:连接谓词中的列名
      • 限制:需要具备可比性
  • 例子

    • 按照Sno属性值连接S表和SC表,并全部输出
    SELECT  S.*, SC.*
    FROM    S,SC
    WHERE   S.sno = SC.sno;
         
         
    • 1
    • 2
    • 3
    • 按照Sno属性自然连接S表和SC表,并输出
    SELECT  S.sno,Sname,Ssex,Sdept,Cno,Grade
    FROM    S,SC
    WHERE   S.Sno = SC.Sno;
         
         
    • 1
    • 2
    • 3
    • 运用连接谓词和选择谓词的复合条件
    SELECT  S.Sno,Sname
    FROM    S,SC
    WHERE   S.Sno = 
                SC.Sno AND
                SC.Cno = '2' AND
                SC.Grade > 90;
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 执行步骤
      • 从SC表中选择符合条件的元组按照Sno等值连接S表
      • 再输出S.Sno和Sname
    • 特点:较普通连接高效

实现:自身连接

  • 定义:一个表与自己进行连接

  • 限制:需要指定别名

  • 例子:对C表进行按照Cpno和Cno进行自身等值连接,输出Cno和Cpno

    SELECT    FIRST.Cno, SECOND.Cpno
    FROM  C FIRST,C SECOND
    WHERE FIRST.Cpno = SECOND.Cno;
         
         
    • 1
    • 2
    • 3
    组略演示
    FIRST.Cno   FIRST.Cpno
            SECOND.Cno  SECOND.Cpno
    =>
    FIRST.Cno SECOND.Cpno
         
         
    • 1
    • 2
    • 3
    • 4
    • 5

实现:外连接

  • 定义:保留正常连接中不符合条件的元组,未连接的部分用空值占位

  • 左外连接:保留坐边,填充未连接的右边(列出全部左边中的元组

  • 右外连接:保留右边,填充未连接的左边(列出全部右边中的元组

  • 格式

    左外
    <表名2> LEFT OUTER JOIN <表名2> ON (<条件表达式>)
    右外
    <表名2> LEFT OUTER JOIN <表名2> ON (<条件表达式>)
         
         
    • 1
    • 2
    • 3
    • 4
  • 例子:S表左外连接SC表

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

实现:多表连接

  • 定义:两个以上的表进行连接

  • 例子:按Sno连接S表和SC表,再将结果按Cno连接C表,选择属性输出

    SELECT    S.Sno,Sname,Cname,Grade
    FROM  S,SC,C
    WHERE S.Sno = SC.Sno AND SC.Cno = C.Cno;
         
         
    • 1
    • 2
    • 3

假如我想:嵌套查询

  • 定义:将查询块嵌套在另外一个查询块的WHERE或者HAVING短语条件中的查询

    • 查询块
    • 定义:SELECT-FROM-WHERE语句
  • 例如

    SELECT    Sname
    FROM  S
    WHERE S   IN(
        SELECT  Sno
        FROM    SC
        WHERE   Cno = '2');
    )
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • SQL结构化的含义:嵌套查询方式

实现:带有IN谓词的子查询

  • 详细的例子:查询与 ”刘某“在同一个系学习的学生(采用分步查询再构造嵌套查询

    • 一、确定”刘某“所在系
    SELECT    Sdept
    FROM  S
    WHERE Sname='刘某';
    假设结果为 'CS'
         
         
    • 1
    • 2
    • 3
    • 4
    • 二、查找所有在’CS’系学习的学生
    SELECT    Sno,Sname,Sdept
    FROM  S
    WHERE Sdept='CS';
         
         
    • 1
    • 2
    • 3
    • 三、构造嵌套查询
    SELECT    Sno,Sname,Sdept
    FROM  S
    WHERE Sdept IN(
    SELECT  Sdept
    FROM    S
    WHERE   Sname='刘某'
    );
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 本例为不相关子查询
    • 子查询不依赖于父查询( 依赖则称:相关子查询( 下目有相关例子

实现:带有比较运算符的子查询

  • 例子:从SC表中找出超过自己Grade值的Cno,输出Sno和Cno

    SELECT    Sno,Cno
    FROM  SC x
    WHERE Grade >=(
    SELECT  AVG(Grade)
    FROM    SC  y
    WHERE   y.Sno = x.Sno;
    )
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 相关子查询需要反复求值(较少遇到
    • 父查询每传递一个值到子查询,子查询针对父查询的一个数据完成全部查询
    • 重复(父查询继续传递值到子查询

实现:带有ANY(SOME)ALL谓词的子查询

  • 子查询返回值

    • 单值:可以用比较运算符, 例如 <=
    • 多值:用到谓词修饰(ALLANY(有的系统用SOME代替ANY
  • 语义

    • > ANY : 大于查询结果中的某个值
    • > ALL:大于所有值
    • < ANY:小于某个值
    • < ALL:小于所有值
    • >= ANY:大于等于某个值
    • >= ALL:大于等于所有值
    • <= ANY:小于等于某个值
    • <= ALL:小于等于所有值
    • =ALL:等于所有值
    • =ANY:等于某一个( IN
    • != ANY:不等于某个值
    • != ALL:不等于所有值( NOT IN
  • 例子:查询非‘CS’系中比‘CS’系中任意一个学生年龄小的学生的姓名和年龄

    SELECT    Sname,Sage
    FROM  S
    WHERE Sage < ANY(
            SELECT  Sage
            FROM    S
            WHERE   Sdept='CS') 
        AND Sdept !='CS';
    
    聚集函数代替版本
    SELECT    Sname,Sage
    FROM  S
    WHERE Sage < (
            SELECT  MAX(Sage)
            FROM    S
            WHERE   Sdept='CS')
          AND   Sdept !='CS';
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 考虑聚合函数代替谓词修饰

实现:带有EXISTS谓词的子查询

  • 定义:EXISTS为代表存在量词

  • 注意:带有EXISTS谓词的子查询不返回任何数据,只产生布尔结果(true or false

  • 例子:查询所有拥有Cno为1的学生的姓名

    SELECT    Sname
    FROM  S
    WHERE EXISTS(
            SELECT  *
            FROM    SC
            WHERE   Sno=S.Sno AND Cno='1');
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 注意:不存在全称量词和蕴含逻辑运算

    • 都需要通过存在量词在构造

假如我想:集合查询

SELECT语句查询的结果是元组的集合,多个SELECT语句的结果可以进行集合操作(元组集合运算

  • 集合操作

    • UNION :并
    • INTERSECT:交
    • EXCEPT:差
  • 限制:操作对象(元组

    • 必须满足列数量、列类型相同
  • 例子:查询’CS‘系学生及年龄不大于19的学生

    SELECT    *
    FROM  S
    WHERE Sdept='CS'
    UNION
    SELECT    *
    FROM  S
    WHERE Sage<=19;
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

假如我想:基于派生表的查询

子查询不仅可以出现在WHERE子句中,还可以出现在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.avg_sno and SC.Grade >= Avg_sc.avg_grade
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • Avg_sc : FROM子句生成的派生表
      • 该表的属性:avg_sno, avg_grade
    • 一些细节
      • 问:什么情况下可以不指定属性列,由SELECT子句后列名决定?
      • 答:当SELECT后列名没有用到聚集函数时
      • 问:什么情况下可以省略AS?
      • 答:基本表均可以省略AS,而模式不可以

走到最后:SELECT语句的一般格式

答案在开头, 发现没有,哈哈哈

 此文章为转载 

猜你喜欢

转载自blog.csdn.net/awiner/article/details/80726283