• 约束条件 ,表与表之间的关系 和多表联合查询***


    一.约束条件
        为了确保数据的完整性 可以给列加上约束条件
        完整性的分类:
            1.实体完整性
            2.域完整性
            3.引用完整性
        1.实体完整性
            实体:即表中的一行(一条)记录 代表一个实体 entity
            实体完整性的作用:标识每一行数据不重复
            约束类型:
                1.1 主键约束(primary key)
                1.2 唯一约束(unique)
                1.3 自动增长列(auto_increment)
            1.1 主键约束
                每一个表中要有一个主键(可以是一列 也可以是多列组成)
                特点: 数据唯一 且不能为null

                第一种添加方式 在创建表的同时 直接添加主键约束
                create table 表名(
                    列名1 列值1 primary key,
                    列名2 列值2,
                    ....
                    列名n 列值n
                )
                第二种添加方式 后期补充主键约束
                create table 表名(
                    列名1 列值1,
                    列名2 列值2,
                    ....
                    列名n 列值n
                )
                alter table 表名 add primary key(列名1);

                联合主键 (由多个列组成的主键)
                create table 表名(
                    列名1 列值1,
                    列名2 列值2,
                    ....
                    列名n 列值n,
                    primary key(列名1,列名2);
                )
                删除主键约束
                alter table 表名 drop primary key;
            1.2 唯一约束
                特点:数据不能重复 值可以为null
                第一种添加方式 在建表的时候添加
                create table 表名(
                    列名1 列值1 约束条件,
                    列名2 列值2 unique,
                    ....
                )
                第二种创建方式 后期追加
                alter table 表名 add unique(列名);
            1.3 自动增长列
                mysql --> auto_increment
                sqlserver --> idenitiy
                oracle --> sequence
                特点:
                    1.设置自动增长的时候 列只能是整型
                    2.当有行被删除 自增会继续自增 在删除行的基础上+1
        2.域完整性
            域完整性的作用:限制此单元格的数据正确 不对照此列的其他单元格
            域代表当前单元格
            域完整性约束:
                数据类型 非空约束(not null) 默认值约束(default)
                2.1 数据类型约束
                2.2 非空约束
                    not null
                    alter table 表名 modify 字段名 字段类型 not null;
                2.3 默认值约束
                    default
                    第一种添加方式 创建表时添加
                    create table 表名(
                        列名1 列值1 约束,
                        列名2 列值2 约束 default 默认值,
                        ....
                        列名n 列值n
                    )
                    第二种添加方式 后期追加
                    alter table 表名 alter 列名 set default 默认值;
        3.引用完整性
            外键约束 foreign key
            用来约束 表与表之间的关系
                建立外键关系 首先 明确 主从关系
                外键一定是在从表中创建 从而找到与主表之间的关系
    例:
                主表 : 部门表 学生表
                从表 : 员工表 分数表
            外键必须要满足的条件:
                1.至少涉及到两张表
                2.建立外键关系 对应列具有相似的数据类型
                3.必须建立索引 主键 和 外键
            注意:外键是可以有重复的 也可以有空值
            创建外键的两种方式
                第一种 在创建表的时候 添加外键
                constraint 外键关系名 foreign key(从表的字段) references 主表名(主表的字段)

                constraint 外键关系名 可以不写 就是一个外键约束的名字 如果不写 系统会自动给
                foreign key(从表的字段) 将 从表中的字段作为外键
                references 主表名(主表的字段) 映射到主表的字段

                CREATE TABLE student(
                    sid INT PRIMARY KEY AUTO_INCREMENT,//默认自动增加
                    sname VARCHAR(10) NOT NULL,//值不能为空
                    gender VARCHAR(10) DEFAULT "男"
                )
                CREATE TABLE score(
                    id INT PRIMARY KEY,
                    score INT,
                    fsid INT,
                    CONSTRAINT fk_student_score FOREIGN KEY(fsid) REFERENCES student(sid)//这里不加分号也不加逗号
                )
                第二种 表已经创建 后期追加
                alter table 主表 add primary key(主表列名)
                alter table 从表 add foreign key(从表列名) references 主表(主表列名)
                注意:
                    1.在从表中添加数据时 外键关联列中存储的数据 必须是主表中存在的数据
                    2.想要删除主表中 正在被从表使用的行 必须先删除从表 再删除主表
                删除外键关联:
                    alter table 表名 drop foreign key 外键关系名//就是你起得名字fk_student_score
    二.表与表之间的关系
        三种关系
         1.一对一 1 vs 1
            person 表 card 表 人表 和 身份证表
            人是主表 身份证表是从表

         2.一对多 1 vs N
         3.多对多 N vs N
    三.多表联合查询***
        在关系型数据库中 一个查询往往会涉及到多张表 多张表如何进行联合查询 就成为了学习sql查询的关键
        如果单纯的只将数据放在一张表中 那么这个表存在大量的数据冗余 这种数据库的设计是不合理的(一般不用)
        1.合并结果集
            union
            union all
            作用 合并结果集 把两个select语句的查询结果合并到一起

            CREATE TABLE g(
                gname VARCHAR(10),
                gage INT
            )
            CREATE TABLE h(
                hname VARCHAR(10),
                hage INT
            )
            INSERT INTO g VALUES("a",1),("b",2),("c",3);
            INSERT INTO h VALUES("d",1),("e",2),("c",3);
            /*union 去除重复数据 合并*/
            SELECT * FROM g UNION SELECT * FROM h;
            /*union all 不去除重复数据 合并*/
            SELECT * FROM g UNION ALL SELECT * FROM h;

            要求:被合并的两个结果集 列数/列类型 必须相同


        2.连接查询
            连接查询 就是求多个表的乘积
            例如 a表 连接 b表 那么查询结果就是 a表*b表
            连接查询 产生 笛卡尔积(在sql中 实现方式 交叉连接 cross join)
            所有的连接方式 都会先产生笛卡尔积 然后 加上限制条件 才会有实际查询意义
            select * from emp,dept;
            join 就是把多个表连接成一个表的手段
            多表查询 分为 内/外连接

            SELECT emp.ename,dept.dname,emp.job FROM emp,dept WHERE emp.deptno = dept.deptno;
            SELECT e.ename,d.dname,e.job FROM emp AS e,dept AS d WHERE e.deptno = d.deptno;
            
            AS关键字 可以给表 起别名 as可省略

            内连接 [INNER]join...on INNER可省略
            [隐式]
            SELECT e.ename,d.dname,e.job FROM emp AS e,dept AS d WHERE e.deptno = d.deptno;
            [显示]
            SELECT e.ename,d.dname,e.job FROM emp e INNER join dept d ON e.deptno = d.deptno;
            特点: 查询结果必须是满足条件的

            外连接 [OUTER]join...on OUTER可省略
                左外连接 Left [OUTER]join
                右外连接 right [OUTER]join
                全外连接 full join (Mysql不支持)

                左外连接
                    以左表为主
                    SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno = d.deptno;
                    左连接 是先查询出左表(以左表为主)
                    然后查询右表 右表中满足条件的显示 不满足条件的显示为null
                右外连接
                    以右表为主
                    SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno = d.deptno;
                    右连接 是先查询出右表(以右表为主)
                    然后查询左表 做表中满足条件的显示 不满足条件的显示为null
                /*练习 查询出 员工姓名 工作 部门 部门所在地 当部门为 RESEARCH 的 不显示 */
                SELECT * FROM emp LEFT JOIN dept ON emp.deptno = dept.deptno WHERE dept.dname!="RESEARCH";
                SELECT * FROM emp LEFT JOIN dept ON emp.deptno = dept.deptno AND dept.dname!="RESEARCH" WHERE emp.ename !="SMITH";

                /* 步骤
                    1.生成笛卡尔积 select * from emp cross join dept
                    2.应用 on 筛选器 emp.deptno = dept.deptno
                    3.看外连接 是 Left join 还是 right join
                        如果是 left join 会以左表为主 作为保留表
                    4.where过滤器 过滤的是 left join 之后的数据
                */
                总结:
                    1.如果sql 用的是Left join
                        on 后面条件 对left表没作用 只是对right表起过滤作用
                        where语句可以对生成临时表后起到过滤 相当于过滤了 left表
                    2.如果sql 用的是right join
                        on 后面条件 对right表没作用 只是对left表起过滤作用
                        where语句可以对生成临时表后起到过滤 相当于过滤了 right表
                on 和 where 的区别:
                    在使用left join时 on 和 where 区别如下:
                        1.on条件是在 生成临时表 时 使用的条件
                            不管on的条件是否为真 都会返回左边表的数据
                        2.where条件在 生成临时表 后 再对临时表进行过滤
                            如果条件不为真 就会全部过滤
            自然连接 Natural join
                自然连接 无需你去给出外键关联等式 它会自动找到这一等式
                两张连接表中 名称 和 类型 完全一致的列 作为条件

                /*自然连接*/
                SELECT * FROM emp NATURAL JOIN dept;
                SELECT * FROM emp NATURAL LEFT JOIN dept;
                SELECT * FROM emp NATURAL RIGHT JOIN dept;
        总结:
            连接查询时 sql查询的核心 按照实际需求来选择对应的类型
            如果选择不当 非但不能提高效率 反而会带来一系列的逻辑错误 或者性能下降
            选择依据:
                1.查两张表关联列相等的数据 用内连接
                2.right表是left表的子集 用左外连接
                3.left表是right表的子集 用右外连接
                4.right 和 left 彼此之间有交集 但是互不为子集 使用全外连接
        3.子查询
            一个select语句中 包含另一个完整的select语句
            子查询 就是 嵌套查询
            子查询出现的位置:
                where 后: 作为查询条件的一部分
                from 后:作为表出现
            当子查询出现在where后 作为条件时 还可以使用如下关键字
                any 任意一个 ---> min
                all 所有 ---> max
            子查询结果集的形式:
                1.单行单列 (用于条件)
                2.单行多列 (用于条件)
                3.多行单列 (用于条件)
                4.多行多列 (表)
            1.单行单列 (用于条件)
                例如 :员工表中 工资高于CLARK的员工都有谁
                分析 :
                    1.查询CLARK的工资
                        select sal from emp where ename="CLARK"
                    2.查询高于CLARK的员工
                        select * from emp where sal > 第一步的结果
                    3.结论
                        select * from emp where sal > (select sal from emp where ename="CLARK")

            2.单行多列 (用于条件)
                例如 :查询员工表中 工作 和 工资 与 MARTIN完全相同的员工信息
                分析 :
                    1.查询MARTIN的工作和工资
                        select job,sal from emp where ename="MARTIN";
                    2.查询与MARTIN工作和工资相同的人
                        select * from emp where (job,sal) in 第一步的结果
                    3.结论
                        select * from emp where (job,sal) in (select job,sal from emp where ename="MARTIN")
            3.多行单列 (用于条件)
                多行子查询 返回多行数据
                在where 使用多行子查询时 要用 all any in

                例如 :查找工资高于30号部门所有人的 员工
                分析 :
                    1.查找30号部门所有人的工资
                        select sal from emp where deptno=30;
                    2.查找高于30号部门所有人工资的员工信息
                        select * from emp where sal > all 第一步的结果
                    3.结论
                        SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30);

                        SELECT * FROM emp WHERE sal > ANY (SELECT sal FROM emp WHERE deptno=30);

                    /*练习 部门编号为20的员工工资 并且 大于部门编号为30的所有人工资的 员工列表*/
                    SELECT * FROM emp WHERE deptno=20 AND sal> ALL(SELECT sal FROM emp WHERE deptno=30)
            4.多行多列 (表)
                例如 :查询员工编号为7788的员工 姓名 工资 部门名称 部门地址
                分析 :涉及到 emp dept两张表
                    1.查询 姓名 和 工资
                        select ename,sal from emp where empno=7788
                    2.查询 部门名称 和 部门地址
                        select e.ename,e.sal,d.dname,d.loc
                        from emp e,dept d
                        where e.deptno = d.deptno and e.empno=7788
                    改版:
                        select e.ename,e.sal,d.dname,d.loc
                        from emp e,(select dname,loc,deptno from dept) d
                        where e.deptno = d.deptno and e.empno=7788

                    /*练习 求7369员工 姓名 经理姓名 经理编号 自己连接自己*/
                        SELECT e1.ename,e2.ename,e2.empno
                        FROM emp e1,(SELECT empno,ename FROM emp) e2
                        WHERE e1.mgr = e2.empno AND e1.empno = 7369

  • 相关阅读:
    P3478 [POI2008]STA-Station
    P2015 二叉苹果树
    P2014 选课 (树型背包模版)
    求树的每个子树的重心
    求树的直径
    Javascript--防抖与节流
    JavaScript中call和apply的区别
    解决谷歌浏览器“此Flash Player与您的地区不相容,请重新安装Flash”问题(最新版)
    matlab实验代码(总)
    表达式树
  • 原文地址:https://www.cnblogs.com/wanghuaying/p/9484112.html
Copyright © 2020-2023  润新知