• 常见通用的 JOIN 查询


    SQL执行循序:

    手写:

    SELECT DISTINCT <query_list> FROM <left_table>
    <join type> JOIN <right_table> ON <join_condition>
    WHERE <wherer_condition>
    GROUP BY <group_by_list>
    HAVING <having_condition>
    ORDER BY <order_by_list>
    LIMIT <limit number>

    机读:

    FROM <left_table> 
    ON <join_condition>
    <join_type> JOIN <right_table>
    WHERE <where_condition>
    GROUP BY <group_by_list>
    HAVING <having_condition>
    SELECT
    DISTINCT <query_list>
    ORDER BY <order_by_condition>
    LIMIT <limit_number>

    总结:

     

    理论图谱:

    MySQL数据库实例:

    1.创建数据库:

    mysql> create database db_test;
    Query OK, 1 row affected (0.01 sec)

     2.使用数据库:

    mysql> use db_test;
    Database changed

    3.创建表、添加数据:

    CREATE TABLE `tb_dept` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门主键',
      `deptName` varchar(30) DEFAULT NULL COMMENT '部门名称',
      `locAdd` varchar(40) DEFAULT NULL COMMENT '楼层',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    
    
    CREATE TABLE `tb_emp` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '员工主键',
      `name` varchar(20) DEFAULT NULL COMMENT '员工姓名',
      `deptId` int(11) DEFAULT NULL COMMENT '部门外键',
      PRIMARY KEY (`id`),
      KEY `fk_dept_id` (`deptId`)
      #CONSTRAINT `fk_dept_id` FOREIGN KEY (`deptId`) REFERENCES `tb_dept` (`id`) COMMENT '部门外键设置, 已经注释掉。'
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    
    INSERT INTO `tb_dept` VALUES ('1', 'RD', '11');
    INSERT INTO `tb_dept` VALUES ('2', 'HR', '12');
    INSERT INTO `tb_dept` VALUES ('3', 'MK', '13');
    INSERT INTO `tb_dept` VALUES ('4', 'MIS', '14');
    INSERT INTO `tb_dept` VALUES ('5', 'FD', '15');
    
    INSERT INTO `tb_emp` VALUES ('1', '张三', '1');
    INSERT INTO `tb_emp` VALUES ('2', '李四', '1');
    INSERT INTO `tb_emp` VALUES ('3', '王二', '1');
    INSERT INTO `tb_emp` VALUES ('4', '麻子', '2');
    INSERT INTO `tb_emp` VALUES ('5', '小马', '2');
    INSERT INTO `tb_emp` VALUES ('6', '马旭', '3');
    INSERT INTO `tb_emp` VALUES ('7', '小丁', '4');
    INSERT INTO `tb_emp` VALUES ('8', '小西', '51');

    tb_emp表数据:

    mysql> select * from tb_emp;
    +----+--------+--------+
    | id | name   | deptId |
    +----+--------+--------+
    |  1 | 张三   |      1 |
    |  2 | 李四   |      1 |
    |  3 | 王二   |      1 |
    |  4 | 麻子   |      2 |
    |  5 | 小马   |      2 |
    |  6 | 马旭   |      3 |
    |  7 | 小丁   |      4 |
    |  8 | 小西   |     51 |
    +----+--------+--------+
    8 rows in set (0.01 sec)

    tb_dept表数据:

    mysql> select * from tb_dept;
    +----+----------+--------+
    | id | deptName | locAdd |
    +----+----------+--------+
    |  1 | RD       | 11     |
    |  2 | HR       | 12     |
    |  3 | MK       | 13     |
    |  4 | MIS      | 14     |
    |  5 | FD       | 15     |
    +----+----------+--------+
    5 rows in set (0.01 sec)

    笛卡儿积:

    mysql> select * from tb_emp, tb_dept;
    +----+--------+--------+----+----------+--------+
    | id | name   | deptId | id | deptName | locAdd |
    +----+--------+--------+----+----------+--------+
    |  1 | 张三   |      1 |  1 | RD       | 11     |
    |  1 | 张三   |      1 |  2 | HR       | 12     |
    |  1 | 张三   |      1 |  3 | MK       | 13     |
    |  1 | 张三   |      1 |  4 | MIS      | 14     |
    |  1 | 张三   |      1 |  5 | FD       | 15     |
    |  2 | 李四   |      1 |  1 | RD       | 11     |
    |  2 | 李四   |      1 |  2 | HR       | 12     |
    |  2 | 李四   |      1 |  3 | MK       | 13     |
    |  2 | 李四   |      1 |  4 | MIS      | 14     |
    |  2 | 李四   |      1 |  5 | FD       | 15     |
    |  3 | 王二   |      1 |  1 | RD       | 11     |
    |  3 | 王二   |      1 |  2 | HR       | 12     |
    |  3 | 王二   |      1 |  3 | MK       | 13     |
    |  3 | 王二   |      1 |  4 | MIS      | 14     |
    |  3 | 王二   |      1 |  5 | FD       | 15     |
    |  4 | 麻子   |      2 |  1 | RD       | 11     |
    |  4 | 麻子   |      2 |  2 | HR       | 12     |
    |  4 | 麻子   |      2 |  3 | MK       | 13     |
    |  4 | 麻子   |      2 |  4 | MIS      | 14     |
    |  4 | 麻子   |      2 |  5 | FD       | 15     |
    |  5 | 小马   |      2 |  1 | RD       | 11     |
    |  5 | 小马   |      2 |  2 | HR       | 12     |
    |  5 | 小马   |      2 |  3 | MK       | 13     |
    |  5 | 小马   |      2 |  4 | MIS      | 14     |
    |  5 | 小马   |      2 |  5 | FD       | 15     |
    |  6 | 马旭   |      3 |  1 | RD       | 11     |
    |  6 | 马旭   |      3 |  2 | HR       | 12     |
    |  6 | 马旭   |      3 |  3 | MK       | 13     |
    |  6 | 马旭   |      3 |  4 | MIS      | 14     |
    |  6 | 马旭   |      3 |  5 | FD       | 15     |
    |  7 | 小丁   |      4 |  1 | RD       | 11     |
    |  7 | 小丁   |      4 |  2 | HR       | 12     |
    |  7 | 小丁   |      4 |  3 | MK       | 13     |
    |  7 | 小丁   |      4 |  4 | MIS      | 14     |
    |  7 | 小丁   |      4 |  5 | FD       | 15     |
    |  8 | 小西   |     51 |  1 | RD       | 11     |
    |  8 | 小西   |     51 |  2 | HR       | 12     |
    |  8 | 小西   |     51 |  3 | MK       | 13     |
    |  8 | 小西   |     51 |  4 | MIS      | 14     |
    |  8 | 小西   |     51 |  5 | FD       | 15     |
    +----+--------+--------+----+----------+--------+
    40 rows in set (0.00 sec)

    查询tb_emp表和tb_dept中公共的数据:

    mysql> select * from tb_emp e
        -> inner join tb_dept d on e.deptId = d.id;
    +----+--------+--------+----+----------+--------+
    | id | name   | deptId | id | deptName | locAdd |
    +----+--------+--------+----+----------+--------+
    |  1 | 张三   |      1 |  1 | RD       | 11     |
    |  2 | 李四   |      1 |  1 | RD       | 11     |
    |  3 | 王二   |      1 |  1 | RD       | 11     |
    |  4 | 麻子   |      2 |  2 | HR       | 12     |
    |  5 | 小马   |      2 |  2 | HR       | 12     |
    |  6 | 马旭   |      3 |  3 | MK       | 13     |
    |  7 | 小丁   |      4 |  4 | MIS      | 14     |
    +----+--------+--------+----+----------+--------+
    7 rows in set (0.00 sec)

    查询tb_emp表中全部的数据:

    mysql> select * from tb_emp e
        -> left join tb_dept d on e.deptId = d.id;
    +----+--------+--------+------+----------+--------+
    | id | name   | deptId | id   | deptName | locAdd |
    +----+--------+--------+------+----------+--------+
    |  1 | 张三   |      1 |    1 | RD       | 11     |
    |  2 | 李四   |      1 |    1 | RD       | 11     |
    |  3 | 王二   |      1 |    1 | RD       | 11     |
    |  4 | 麻子   |      2 |    2 | HR       | 12     |
    |  5 | 小马   |      2 |    2 | HR       | 12     |
    |  6 | 马旭   |      3 |    3 | MK       | 13     |
    |  7 | 小丁   |      4 |    4 | MIS      | 14     |
    |  8 | 小西   |     51 | NULL | NULL     | NULL   |    #该条数据为 tb_emp 表中独有的数据, tb_dept 表中的字段用 null 占位
    +----+--------+--------+------+----------+--------+
    8 rows in set (0.00 sec)

    查询tb_dept表中全部的数据:

    mysql> select * from tb_emp e
        -> right join tb_dept d on e.deptId = d.id;
    +------+--------+--------+----+----------+--------+
    | id   | name   | deptId | id | deptName | locAdd |
    +------+--------+--------+----+----------+--------+
    |    1 | 张三   |      1 |  1 | RD       | 11     |
    |    2 | 李四   |      1 |  1 | RD       | 11     |
    |    3 | 王二   |      1 |  1 | RD       | 11     |
    |    4 | 麻子   |      2 |  2 | HR       | 12     |
    |    5 | 小马   |      2 |  2 | HR       | 12     |
    |    6 | 马旭   |      3 |  3 | MK       | 13     |
    |    7 | 小丁   |      4 |  4 | MIS      | 14     |
    | NULL | NULL   |   NULL |  5 | FD       | 15     |     #该条数据为 tb_dept 表中独有的数据, tb_emp 表中的字段用 null 占位
    +------+--------+--------+----+----------+--------+
    8 rows in set (0.01 sec)

    查询tb_emp表中独有的数据:

    mysql> select * from tb_emp e
        -> left join tb_dept d on e.deptId = d.id
        -> where d.id is null;
    +----+--------+--------+------+----------+--------+
    | id | name   | deptId | id   | deptName | locAdd |
    +----+--------+--------+------+----------+--------+
    |  8 | 小西   |     51 | NULL | NULL     | NULL   |
    +----+--------+--------+------+----------+--------+
    1 row in set (0.00 sec)

    查询tb_dept表中独有的数据:

    mysql> select * from tb_emp e
        -> right join tb_dept d on e.deptId = d.id
        -> where e.deptId is null;
    +------+------+--------+----+----------+--------+
    | id   | name | deptId | id | deptName | locAdd |
    +------+------+--------+----+----------+--------+
    | NULL | NULL |   NULL |  5 | FD       | 15     |
    +------+------+--------+----+----------+--------+
    1 row in set (0.00 sec)

    查询tb_emp和tb_dept表中所有的数据:

    mysql> select * from tb_emp e
        -> full outer join tb_dept d on e.deptId = d.id;
    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'full outer join tb_dept d on e.deptId = d.id' at line 2

    出错原因:mysql 中不支持这种连接方式。

    解决办法:左连接数据和右连接数据相加,将公共的部分去重。

    mysql> select * from tb_emp e 
        -> left join tb_dept d on e.deptId = d.id
        -> union     #去重
        -> select * from tb_emp e
        -> right join tb_dept d on e.deptId = d.id;
    +------+--------+--------+------+----------+--------+
    | id   | name   | deptId | id   | deptName | locAdd |
    +------+--------+--------+------+----------+--------+
    |    1 | 张三   |      1 |    1 | RD       | 11     |
    |    2 | 李四   |      1 |    1 | RD       | 11     |
    |    3 | 王二   |      1 |    1 | RD       | 11     |
    |    4 | 麻子   |      2 |    2 | HR       | 12     |
    |    5 | 小马   |      2 |    2 | HR       | 12     |
    |    6 | 马旭   |      3 |    3 | MK       | 13     |
    |    7 | 小丁   |      4 |    4 | MIS      | 14     |
    |    8 | 小西   |     51 | NULL | NULL     | NULL   |    #该条数据为 tb_emp 表中独有的数据, tb_dept 表中的字段用 null 占位
    | NULL | NULL   |   NULL |    5 | FD       | 15     |    #该条数据为 tb_dept 表中独有的数据, tb_emp 表中的字段用 null 占位
    +------+--------+--------+------+----------+--------+
    9 rows in set (0.00 sec)

    查询tb_emp和tb_dept表中独有的数据:

    mysql> select * from tb_emp e
        -> left join tb_dept d on e.deptId = d.id
        -> where d.id is null
        -> union
        -> select * from tb_emp e
        -> right join tb_dept d on e.deptId = d.id
        -> where e.deptId is null;
    +------+--------+--------+------+----------+--------+
    | id   | name   | deptId | id   | deptName | locAdd |
    +------+--------+--------+------+----------+--------+
    |    8 | 小西   |     51 | NULL | NULL     | NULL   |
    | NULL | NULL   |   NULL |    5 | FD       | 15     |
    +------+--------+--------+------+----------+--------+
    2 rows in set (0.00 sec)
  • 相关阅读:
    Mutex和Lock
    Thread和Promise以及packaged_task
    async和Future
    《并行程序设计导论》——读书笔记汇总
    UnrealEngine4蓝图可视化编程 完整例子 勘误
    BOOST下载
    sql 解析xml
    AutoResetEvent 笔记2
    ssh免密登录设置 (普通用户和root用户)
    npm设置淘宝镜像
  • 原文地址:https://www.cnblogs.com/chinda/p/7079765.html
Copyright © 2020-2023  润新知