• MYSQL初级学习笔记五:连接查询!(视频序号:初级_37-41)


    知识点七:连接查询(37-41)

    什么是连接查询:

      连接查询是将两个或两个以上的表按某个条件连接起来,从中选取需要的数据。连接查询是同时查询两个或两个以上的表时使用的。当不同的表中存在相同意义的字段时,可以通过该字段连接这几个表。

    1 -- 查询cms_user id,username
    2 -- provinces,proName
    3 SELECT cms_user.id,username,proName FROM cms_user,provinces;    --笛卡儿积
    4 
    5 -- cms_user的proId对应省份表中的id
    6 SELECT cms_user.id,username,proName FROM cms_user,provinces
    7 WHERE cms_user.proId=provinces.id;
    连接查询测试

    内连接查询:

      CROSS JOIN | INNER JOIN | JOIN

      通过ON 连接查询

      显示两个表中符合连接条件的记录

      1 -- 查询cms_user表中id,username,email,sex
      2 -- 查询provinces表proName
      3 SELECT u.id,u.username,u.email,u.sex,p.proName
      4 FROM cms_user AS u
      5 INNER JOIN provinces AS p
      6 ON u.proId=p.id;
      7 
      8 
      9 SELECT u.id,u.username,u.email,u.sex,p.proName
     10 FROM provinces AS p
     11 CROSS JOIN cms_user AS u
     12 ON u.proId=p.id;
     13 
     14 
     15 SELECT u.id,u.username,u.email,u.sex,p.proName
     16 FROM provinces AS p
     17 JOIN cms_user AS u
     18 ON u.proId=p.id;
     19 
     20 
     21 -- 查询cms_user id,username,sex
     22 -- 查询provinces proName
     23 -- 条件是cms_user的性别为男的用户
     24 SELECT u.id,u.username,u.sex,p.proName 
     25 FROM cms_user AS u
     26 JOIN 
     27 provinces AS p
     28 ON u.proId=p.id
     29 WHERE u.sex='';
     30 
     31 -- 根据proName分组
     32 SELECT u.id,u.username,u.sex,p.proName,COUNT(*) AS totalUsers,GROUP_CONCAT(username)
     33 FROM cms_user AS u
     34 JOIN
     35 provinces AS p
     36 ON u.proId=p.id
     37 WHERE u.sex=''
     38 GROUP BY p.proName;
     39 
     40 -- 对分组结果进行筛选,选出组中人数>=1的
     41 SELECT u.id,u.username,u.sex,p.proName,COUNT(*) AS totalUsers,GROUP_CONCAT(username)
     42 FROM cms_user AS u
     43 JOIN
     44 provinces AS p
     45 ON u.proId=p.id
     46 WHERE u.sex=''
     47 GROUP BY p.proName
     48 HAVING COUNT(*)>=1;
     49 
     50 
     51 --  按照id升序排列
     52 SELECT u.id,u.username,u.sex,p.proName,COUNT(*) AS totalUsers,GROUP_CONCAT(username)
     53 FROM cms_user AS u
     54 JOIN
     55 provinces AS p
     56 ON u.proId=p.id
     57 WHERE u.sex=''
     58 GROUP BY p.proName
     59 HAVING COUNT(*)>=1
     60 ORDER BY u.id ASC;
     61 
     62 
     63 -- 限制显示条数 前2条
     64 SELECT u.id,u.username,u.sex,p.proName,COUNT(*) AS totalUsers,GROUP_CONCAT(username)
     65 FROM cms_user AS u
     66 JOIN
     67 provinces AS p
     68 ON u.proId=p.id
     69 WHERE u.sex=''
     70 GROUP BY p.proName
     71 HAVING COUNT(*)>=1
     72 ORDER BY u.id ASC
     73 LIMIT 0,2;
     74 
     75 -- 查询cms_news中的id,title,
     76 --  查询cms_cate 中的cateName
     77 SELECT n.id,n.title,c.cateName FROM 
     78 cms_news AS n
     79 JOIN 
     80 cms_cate AS c
     81 ON n.cId=c.id;
     82 
     83 -- cms_news id,title
     84 -- cms_admin username,role
     85 SELECT n.id,n.title,a.username,a.role
     86 FROM 
     87 cms_news AS n
     88 JOIN
     89 cms_admin AS a
     90 ON n.aId=a.id;
     91 
     92 -- cms_news id ,title
     93 -- cms_cate cateName
     94 -- cms_admin username,role
     95 SELECT n.id,n.title,c.cateName,a.username,a.role
     96 FROM cms_cate AS c
     97 JOIN 
     98 cms_news AS n
     99 ON n.cId=c.id
    100 JOIN 
    101 cms_admin AS a
    102 ON n.aId=a.id;
    内连接查询测试

    外连接查询:

      左外连接:LEFT [OUTER] JOIN

        显示左表的全部记录及右表符合连接条件的记录

      右外连接:RIGHT [OUTER] JOIN

        显示右表的全部记录以及左表符合连接条件的记录

     1 -- 插入错误的数据
     2 INSERT cms_user(username,password,regTime,proId)
     3 VALUES('TEST2','TEST2','1381203974',20);
     4 
     5 
     6 -- 左外连接
     7 SELECT u.id,u.username,u.email,u.sex,p.proName
     8 FROM cms_user AS u
     9 LEFT JOIN provinces AS p
    10 ON u.proId=p.id;
    11 
    12 
    13 SELECT u.id,u.username,u.email,u.sex,p.proName
    14 FROM provinces AS p
    15 LEFT JOIN cms_user AS u
    16 ON u.proId=p.id;
    17 
    18 
    19 -- 右外连接
    20 SELECT u.id,u.username,u.email,u.sex,p.proName
    21 FROM provinces AS p
    22 RIGHT JOIN cms_user AS u
    23 ON u.proId=p.id;
    24 
    25 SELECT u.id,u.username,u.email,u.sex,p.proName
    26 FROM provinces AS p
    27 RIGHT JOIN cms_user AS u
    28 ON u.proId=p.id;
    外连接查询测试

    外键:

      外键是表的一个特殊字段,被参照的是主表,外键所在字段的表为子表。设置外键的原则需要记住,就是依赖于数据库中已存在的表的主键。外键的作用是建立该表与其父表的关联关系。父表中对记录做操作时,子表中与之对应的信息也应右相应的改变。

      外键的作用时保持数据的一致性和完整性,可以实现一对一或一对多的关系。

      注意:

        父表和子表必须使用相同的存储引擎,而且禁止使用临时表。

        数据表的存储引擎只能是InnoDB

        外键列和参照列必须具有相似的数据类型。其中数字的长度或是否有符号位必须相同;而字符的长度则可以不同。

        外键列和参照列必须创建索引。如果外键列不存在索引的话 ,MySQL将自动创建索引。

      外键约束的参照操作:

        CASCADE:从父表删除或者更新且自动删除或更新子表中匹配的行。

     1 --删除部门表和员工表重新创建
     2 ----------------
     3 CREATE TABLE IF NOT EXISTS department(
     4 id TINYINT UNSIGNED AUTO_INCREMENT KEY,
     5 depName VARCHAR(20) NOT NULL UNIQUE
     6 )ENGINE=INNODB;
     7 
     8 INSERT department(depName) VALUES('教学部'),
     9 ('市场部'),
    10 ('运营部'),
    11 ('督导部');
    12 
    13 --(当父表进行删除或更新时子表自动删除或者更新) CASCADE
    14 -- 创建员工表employee(子表)
    15 -- id ,username ,depId
    16 CREATE TABLE IF NOT EXISTS employee(
    17 id SMALLINT UNSIGNED AUTO_INCREMENT KEY,
    18 username VARCHAR(20) NOT NULL UNIQUE,
    19 depId TINYINT UNSIGNED,
    20 FOREIGN KEY(depId) REFERENCES department(id) ON DELETE CASCADE ON UPDATE CASCADE
    21 )ENGINE=INNODB;
    22 
    23 INSERT employee(username,depId) VALUES('king',1),
    24 ('queen',2),
    25 ('张三',3),
    26 ('李四',4),
    27 ('王五',1);
    28 
    29 -- 删除部门表中的第一个部门
    30 DELETE FROM department WHERE id=1;
    31 
    32 UPDATE department SET id=id+10;
    CASCADE测试

        SET NULL:从父表删除或更新行,并设置子表中的外键列为NULL。如果使用该选项,必须保证子表列没有指定的NOT NULL。

     1 --SET NULL
     2 DROP TABLE employee,department;
     3 --------------------
     4 CREATE TABLE IF NOT EXISTS department(
     5 id TINYINT UNSIGNED AUTO_INCREMENT KEY,
     6 depName VARCHAR(20) NOT NULL UNIQUE
     7 )ENGINE=INNODB;
     8 
     9 INSERT department(depName) VALUES('教学部'),
    10 ('市场部'),
    11 ('运营部'),
    12 ('督导部');
    13 
    14 -- 创建员工表employee(子表)
    15 -- id ,username ,depId
    16 CREATE TABLE IF NOT EXISTS employee(
    17 id SMALLINT UNSIGNED AUTO_INCREMENT KEY,
    18 username VARCHAR(20) NOT NULL UNIQUE,
    19 depId TINYINT UNSIGNED,
    20 FOREIGN KEY(depId) REFERENCES department(id) ON DELETE SET NULL ON UPDATE SET NULL
    21 )ENGINE=INNODB;
    22 
    23 INSERT employee(username,depId) VALUES('king',1),
    24 ('queen',2),
    25 ('张三',3),
    26 ('李四',4),
    27 ('王五',1);
    28 --删除部门一,查询员工表内容
    29 DELETE FROM department WHERE id=1;
    30 UPDATE department SET id=id+10;
    SET NULL测试

        RESTRICT:拒绝对父表的删除或更新操作。

        NO ACTION:标准MSQL的关键字,在MySQL中与RESTRICT相同。

     1 -- 创建部门表department(主表)
     2 -- id depName 
     3 CREATE TABLE IF NOT EXISTS department(
     4 id TINYINT UNSIGNED AUTO_INCREMENT KEY,
     5 depName VARCHAR(20) NOT NULL UNIQUE
     6 )ENGINE=INNODB;
     7 INSERT department(depName) VALUES('教学部'),
     8 ('市场部'),
     9 ('运营部'),
    10 ('督导部');
    11 
    12 -- 创建员工表employee(子表)
    13 -- id ,username ,depId
    14 CREATE TABLE IF NOT EXISTS employee(
    15 id SMALLINT UNSIGNED AUTO_INCREMENT KEY,
    16 username VARCHAR(20) NOT NULL UNIQUE,
    17 depId TINYINT UNSIGNED
    18 )ENGINE=INNODB;
    19 INSERT employee(username,depId) VALUES('king',1),
    20 ('queen',2),
    21 ('张三',3),
    22 ('李四',4),
    23 ('王五',1);
    24 
    25 --查询员工表的id,username和所在部门名
    26 SELECT e.id,e.username,d.depName FROM
    27 employee AS e
    28 JOIN
    29 department AS d
    30 ON e.depId=d.id;
    31 
    32 
    33 -- 删除督导部
    34 DELETE FROM department WHERE depName='督导部';
    35 
    36 --删除部门表和员工表
    37 DROP TABLE IF EXISTS department;
    38 DROP TABLE IF EXISTS employee;
    39 
    40 --没有外键时,各个表中的数据没有关联,当两个表有关联时,删除其中一个表中的数据时,对另一个表没产生影响。
    没有外键测试
     1 -- 创建部门表department(主表)
     2 -- id depName 
     3 CREATE TABLE IF NOT EXISTS department(
     4 id TINYINT UNSIGNED AUTO_INCREMENT KEY,
     5 depName VARCHAR(20) NOT NULL UNIQUE
     6 )ENGINE=INNODB;
     7 INSERT department(depName) VALUES('教学部'),
     8 ('市场部'),
     9 ('运营部'),
    10 ('督导部');
    11 
    12 -- 创建员工表employee(子表)(有外键)
    13 -- id ,username ,depId
    14 CREATE TABLE IF NOT EXISTS employee(
    15 id SMALLINT UNSIGNED AUTO_INCREMENT KEY,
    16 username VARCHAR(20) NOT NULL UNIQUE,
    17 depId TINYINT UNSIGNED,
    18 FOREIGN KEY(depId) REFERENCES department(id)
    19 )ENGINE=INNODB;
    20 INSERT employee(username,depId) VALUES('king',1),
    21 ('queen',2),
    22 ('张三',3),
    23 ('李四',4),
    24 ('王五',1);
    25 
    26 -- 删除主表中的记录(会报错,得先删除employee表中的depTd为1数据的删除)
    27 DELETE FROM department WHERE id=1;
    28 
    29 -- 删除employee中的属于1部门的人,再删除主表中id为1的数据
    30 DELETE FROM employee WHERE depId=1;
    31 DELETE FROM department WHERE id=1;
    32 
    33 --在子表中添加数据时,当与主表中关联的数据在主表中查不到时也会报错
    34 INSERT employee(username,depId) VALUES('test',11);
    有外键测试
     1 -- 删除员工表
     2 DROP TABLE employee;
     3 
     4 --自定义外键名称
     5 CREATE TABLE IF NOT EXISTS employee(
     6 id SMALLINT UNSIGNED AUTO_INCREMENT KEY,
     7 username VARCHAR(20) NOT NULL UNIQUE,
     8 depId TINYINT UNSIGNED,
     9 CONSTRAINT emp_fk_dep FOREIGN KEY(depId) REFERENCES department(id)
    10 )ENGINE=INNODB;
    11 
    12 
    13 INSERT employee(username,depId) VALUES('king',3),
    14 ('queen',2),
    15 ('张三',3),
    16 ('李四',4),
    17 ('王五',2);
    18 
    19 -- 删除外键(没删除索引)
    20 ALTER TABLE employee DROP FOREIGN KEY emp_fk_dep;
    21 
    22 --删除部门表id为2的部门
    23 DELETE FROM department WHERE id=2;
    24 
    25 -- 添加外键(不成功以为刚才删除了部门表id为2的部门但员工表还有索引指向2部门)
    26 ALTER TABLE employee ADD CONSTRAINT emp_fk_dep FOREIGN KEY(depId) REFERENCES department(id);
    27 
    28 --删除员工表depId为2的员工才能添加上
    29 DELETE FROM employee WHERE depId=2;
    30 --再添加就成功了
    31 ALTER TABLE employee ADD CONSTRAINT emp_fk_dep FOREIGN KEY(depId) REFERENCES department(id);
    删除外键测试

    联合查询:

        UNION:

        UNION ALL:

        UNION和UNION ALL区别是UNION去掉相同记录,UNION ALL是简单的合并到一起。

    1 -- 联合查询(两个表查询数量必须一样)
    2 SELECT username FROM employee UNION SELECT username FROM cms_user;
    3 
    4 SELECT username FROM employee UNION ALL SELECT username FROM cms_user;
    5 
    6 SELECT id,username FROM employee UNION ALL SELECT username,age FROM cms_user;
    联合查询测试
    这都是我对自己学习过程的理解,如有错误请指出!我算一个小白了。
  • 相关阅读:
    【LGR-070】洛谷 3 月月赛-官方题解
    洛谷P1034 矩形覆盖
    <C和指针---读书笔记9>
    <C和指针---读书笔记8>
    <C和指针---读书笔记7>
    <C和指针---读书笔记6>
    <C和指针---读书笔记1>
    <C和指针---读书笔记2>
    <C和指针---读书笔记5>
    <C和指针---读书笔记4>
  • 原文地址:https://www.cnblogs.com/darwinli/p/8996313.html
Copyright © 2020-2023  润新知