zoukankan      html  css  js  c++  java
  • MySQL教程77-CROSS JOIN 交叉连接

    之间所讲的查询语句都是针对一个表的,但是在关系型数据库中,表与表之间是有联系的,所以在实际应用中,经常使用多表查询。多表查询就是同时查询两个或两个以上的表。

    在 MySQL 中,多表查询主要有交叉连接、内连接和外连接。由于篇幅有限,这里主要讲解交叉连接查询。内连接和外连接将在接下来的教程中讲解。

    交叉连接(CROSS JOIN)一般用来返回连接表的笛卡尔积。

    笛卡尔积

    笛卡尔积(Cartesian product)是指两个集合 X 和 Y 的乘积。

    例如,有 A 和 B 两个集合,它们的值如下:

    A = {1,2}
    B = {3,4,5}

    集合 A×B 和 B×A 的结果集分别表示为:

    A×B={(1,3), (1,4), (1,5), (2,3), (2,4), (2,5) };
    B×A={(3,1), (3,2), (4,1), (4,2), (5,1), (5,2) };

    以上 A×B 和 B×A 的结果就分别叫做两个集合的笛卡尔积。

    并且,从以上结果我们可以看出:

    • 两个集合相乘,不满足交换率,即 A×B≠B×A。
    • A 集合和 B 集合的笛卡尔积是 A 集合的元素个数 × B 集合的元素个数

    多表查询遵循的算法就是以上提到的笛卡尔积,表与表之间的连接可以看成是在做乘法运算。在实际应用中,应避免使用笛卡尔积,因为笛卡尔积中容易存在大量的不合理数据,简单来说就是容易导致查询结果重复、混乱。

    交叉连接的语法格式如下:

    SELECT <字段名> FROM <表1> CROSS JOIN <表2> [WHERE子句]

    SELECT <字段名> FROM <表1>, <表2> [WHERE子句] 

    语法说明如下:

    • 字段名:需要查询的字段名称。
    • <表1><表2>:需要交叉连接的表名。
    • WHERE 子句:用来设置交叉连接的查询条件。

    注意:多个表交叉连接时,在 FROM 后连续使用 CROSS JOIN 或,即可。以上两种语法的返回结果是相同的,但是第一种语法才是官方建议的标准写法。

    当连接的表之间没有关系时,我们会省略掉 WHERE 子句,这时返回结果就是两个表的笛卡尔积,返回结果数量就是两个表的数据行相乘。需要注意的是,如果每个表有 1000 行,那么返回结果的数量就有 1000×1000 = 1000000 行,数据量是非常巨大的。

    交叉连接可以查询两个或两个以上的表,为了更好的理解,下面先讲解两个表的交叉连接查询。

    例 1

    查询学生信息表和科目信息表,并得到一个笛卡尔积。

    为了方便观察学生信息表和科目表交叉连接后的运行结果,我们先分别查询出这两个表的数据,再进行交叉连接查询。

    1)查询 tb_students_info 表中的数据,SQL 语句和运行结果如下:

    mysql> SELECT * FROM tb_students_info;
    +----+--------+------+------+--------+-----------+
    | id | name   | age  | sex  | height | course_id |
    +----+--------+------+------+--------+-----------+
    |  1 | Dany   |   25 ||    160 |         1 |
    |  2 | Green  |   23 ||    158 |         2 |
    |  3 | Henry  |   23 ||    185 |         1 |
    |  4 | Jane   |   22 ||    162 |         3 |
    |  5 | Jim    |   24 ||    175 |         2 |
    |  6 | John   |   21 ||    172 |         4 |
    |  7 | Lily   |   22 ||    165 |         4 |
    |  8 | Susan  |   23 ||    170 |         5 |
    |  9 | Thomas |   22 ||    178 |         5 |
    | 10 | Tom    |   23 ||    165 |         5 |
    +----+--------+------+------+--------+-----------+
    10 rows in set (0.00 sec)

    2)查询 tb_course 表中的数据,SQL 语句和运行结果如下:

    mysql> SELECT * FROM tb_course;
    +----+-------------+
    | id | course_name |
    +----+-------------+
    |  1 | Java        |
    |  2 | MySQL       |
    |  3 | Python      |
    |  4 | Go          |
    |  5 | C++         |
    +----+-------------+
    5 rows in set (0.00 sec)

    3)使用 CROSS JOIN 查询出两张表中的笛卡尔积,SQL 语句和运行结果如下:

    mysql> SELECT * FROM tb_course CROSS JOIN tb_students_info;
    +----+-------------+----+--------+------+------+--------+-----------+
    | id | course_name | id | name   | age  | sex  | height | course_id |
    +----+-------------+----+--------+------+------+--------+-----------+
    |  1 | Java        |  1 | Dany   |   25 ||    160 |         1 |
    |  2 | MySQL       |  1 | Dany   |   25 ||    160 |         1 |
    |  3 | Python      |  1 | Dany   |   25 ||    160 |         1 |
    |  4 | Go          |  1 | Dany   |   25 ||    160 |         1 |
    |  5 | C++         |  1 | Dany   |   25 ||    160 |         1 |
    |  1 | Java        |  2 | Green  |   23 ||    158 |         2 |
    |  2 | MySQL       |  2 | Green  |   23 ||    158 |         2 |
    |  3 | Python      |  2 | Green  |   23 ||    158 |         2 |
    |  4 | Go          |  2 | Green  |   23 ||    158 |         2 |
    |  5 | C++         |  2 | Green  |   23 ||    158 |         2 |
    |  1 | Java        |  3 | Henry  |   23 ||    185 |         1 |
    |  2 | MySQL       |  3 | Henry  |   23 ||    185 |         1 |
    |  3 | Python      |  3 | Henry  |   23 ||    185 |         1 |
    |  4 | Go          |  3 | Henry  |   23 ||    185 |         1 |
    |  5 | C++         |  3 | Henry  |   23 ||    185 |         1 |
    |  1 | Java        |  4 | Jane   |   22 ||    162 |         3 |
    |  2 | MySQL       |  4 | Jane   |   22 ||    162 |         3 |
    |  3 | Python      |  4 | Jane   |   22 ||    162 |         3 |
    |  4 | Go          |  4 | Jane   |   22 ||    162 |         3 |
    |  5 | C++         |  4 | Jane   |   22 ||    162 |         3 |
    |  1 | Java        |  5 | Jim    |   24 ||    175 |         2 |
    |  2 | MySQL       |  5 | Jim    |   24 ||    175 |         2 |
    |  3 | Python      |  5 | Jim    |   24 ||    175 |         2 |
    |  4 | Go          |  5 | Jim    |   24 ||    175 |         2 |
    |  5 | C++         |  5 | Jim    |   24 ||    175 |         2 |
    |  1 | Java        |  6 | John   |   21 ||    172 |         4 |
    |  2 | MySQL       |  6 | John   |   21 ||    172 |         4 |
    |  3 | Python      |  6 | John   |   21 ||    172 |         4 |
    |  4 | Go          |  6 | John   |   21 ||    172 |         4 |
    |  5 | C++         |  6 | John   |   21 ||    172 |         4 |
    |  1 | Java        |  7 | Lily   |   22 ||    165 |         4 |
    |  2 | MySQL       |  7 | Lily   |   22 ||    165 |         4 |
    |  3 | Python      |  7 | Lily   |   22 ||    165 |         4 |
    |  4 | Go          |  7 | Lily   |   22 ||    165 |         4 |
    |  5 | C++         |  7 | Lily   |   22 ||    165 |         4 |
    |  1 | Java        |  8 | Susan  |   23 ||    170 |         5 |
    |  2 | MySQL       |  8 | Susan  |   23 ||    170 |         5 |
    |  3 | Python      |  8 | Susan  |   23 ||    170 |         5 |
    |  4 | Go          |  8 | Susan  |   23 ||    170 |         5 |
    |  5 | C++         |  8 | Susan  |   23 ||    170 |         5 |
    |  1 | Java        |  9 | Thomas |   22 ||    178 |         5 |
    |  2 | MySQL       |  9 | Thomas |   22 ||    178 |         5 |
    |  3 | Python      |  9 | Thomas |   22 ||    178 |         5 |
    |  4 | Go          |  9 | Thomas |   22 ||    178 |         5 |
    |  5 | C++         |  9 | Thomas |   22 ||    178 |         5 |
    |  1 | Java        | 10 | Tom    |   23 ||    165 |         5 |
    |  2 | MySQL       | 10 | Tom    |   23 ||    165 |         5 |
    |  3 | Python      | 10 | Tom    |   23 ||    165 |         5 |
    |  4 | Go          | 10 | Tom    |   23 ||    165 |         5 |
    |  5 | C++         | 10 | Tom    |   23 ||    165 |         5 |
    +----+-------------+----+--------+------+------+--------+-----------+
    50 rows in set (0.00 sec)
    View Code

    由运行结果可以看出,tb_course 和 tb_students_info 表交叉连接查询后,返回了 50 条记录。可以想象,当表中的数据较多时,得到的运行结果会非常长,而且得到的运行结果也没太大的意义。所以,通过交叉连接的方式进行多表查询的这种方法并不常用,我们应该尽量避免这种查询。

    例 2

    查询 tb_course 表中的 id 字段和 tb_students_info 表中的 course_id 字段相等的内容, SQL 语句和运行结果如下:

    mysql> SELECT * FROM tb_course CROSS JOIN tb_students_info 
        -> WHERE tb_students_info.course_id = tb_course.id;
    +----+-------------+----+--------+------+------+--------+-----------+
    | id | course_name | id | name   | age  | sex  | height | course_id |
    +----+-------------+----+--------+------+------+--------+-----------+
    |  1 | Java        |  1 | Dany   |   25 ||    160 |         1 |
    |  2 | MySQL       |  2 | Green  |   23 ||    158 |         2 |
    |  1 | Java        |  3 | Henry  |   23 ||    185 |         1 |
    |  3 | Python      |  4 | Jane   |   22 ||    162 |         3 |
    |  2 | MySQL       |  5 | Jim    |   24 ||    175 |         2 |
    |  4 | Go          |  6 | John   |   21 ||    172 |         4 |
    |  4 | Go          |  7 | Lily   |   22 ||    165 |         4 |
    |  5 | C++         |  8 | Susan  |   23 ||    170 |         5 |
    |  5 | C++         |  9 | Thomas |   22 ||    178 |         5 |
    |  5 | C++         | 10 | Tom    |   23 ||    165 |         5 |
    +----+-------------+----+--------+------+------+--------+-----------+
    10 rows in set (0.01 sec)

    如果在交叉连接时使用 WHERE 子句,MySQL 会先生成两个表的笛卡尔积,然后再选择满足 WHERE 条件的记录。因此,表的数量较多时,交叉连接会非常非常慢。一般情况下不建议使用交叉连接。

    在 MySQL 中,多表查询一般使用内连接和外连接,它们的效率要高于交叉连接。

  • 相关阅读:
    Serialization and deserialization are bottlenecks in parallel and distributed computing, especially in machine learning applications with large objects and large quantities of data.
    Introduction to the Standard Directory Layout
    import 原理 及 导入 自定义、第三方 包
    403 'Forbidden'
    https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
    These interactions can be expressed as complicated, large scale graphs. Mining data requires a distributed data processing engine
    mysqldump --flush-logs
    mysql dump 参数
    mysql dump 参数
    如果是在有master上开启了该参数,记得在slave端也要开启这个参数(salve需要stop后再重新start),否则在master上创建函数会导致replaction中断。
  • 原文地址:https://www.cnblogs.com/no-celery/p/13544365.html
Copyright © 2011-2022 走看看