多表查询【联接查询】

 

六、多表查询【联接查询】

         联接查询是又笛卡尔乘积运算再加一个选取运算构成的查询。首先用笛卡尔乘积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,确保只把分别来自两个数据集合并且有重叠部分的行合并在一起。联接的全部意义在于水平方向上合并两个数据集合,并产生一个新的结果集合。

       联接条件可在FROM或WHERE子句中指定,建议在FROM子句中指定联接条件。WHERE和HAVING子句还可以包含搜索条件,以进一步筛选根据联接条件选择的行。

       联接可以分为内部联接(INNERJOIN)、外部联接(OUTER JOIN)和交叉联接(CROSS JOIN)3种。

6.1、内链接[内部联接]

            内联接是使用比较运算符比较要联接列中的值的联接,内联接也叫联接。可以分为:

等值联接:让表之间的字段以“等值”建立联接关系

                     不等值联接:让表之间的字段以“不等值”建立联接关系

自然联接:同一张表自己和自己联接

        内联接使用JOIN进行联接,具体语法格式如下:

            SELECT  fieldlist FROM table1 [INNER] JOIN table2 ONtable1.column=table2.column

        参数说明:

            Fieldlist:搜索条件

            table1[INNER] JOIN table2:将table1表与table2表进行内部联接

            table1.column=table2.column:table1表中与table2表中相同的列

      6.1.1、自然联接

        【列6.1.1】

            ySQL[yuancheng]> select * from students,classes where students.ClassID=classes.ClassID;

+-------+---------------+-----+--------+---------+-----------+---------+----------------+----------+

| StuID | Name         | Age | Gender | ClassID | TeacherID | ClassID | Class          | NumOfStu |

+-------+---------------+-----+--------+---------+-----------+---------+----------------+----------+

|     1 | ShiZhongyu   |  22 | M     |       2 |         3 |       2 | Emei Pai       |       7 |

|     2 | ShiPotian    |  22 | M     |       1 |         7 |      1 | Shaolin Pai    |       10 |

|     3 | XieYanke     |  53 | M     |       2 |        16 |       2 | Emei Pai       |       7 |

|     4 | DingDian     |  32 | M     |       4 |         4 |       4 | Wudang Pai     |      12 |

|     5 | YuYutong     |  26 | M     |       3 |         1 |       3 | QingCheng Pai  |      11 |

|     6 | ShiQing      |  46 | M     |       5 |      NULL |       5 | Riyue Shenjiao |       31 |

6.1.2、等值联接       

【列 6.1】 查找students和teachers表中TeacherID等于TID的所有数据

        MySQL[yuancheng]>  select * from studentsjoin teachers on students.TeacherID=teachers.TID;

+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+

| StuID | Name       | Age | Gender | ClassID | TeacherID | TID | Name          | Age | Gender |

+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+

|     5 | YuYutong   |  26 | M     |       3 |         1 |  1 | Song Jiang    |  45 | M     |

|     1 | ShiZhongyu |  22 | M      |      2 |         3 |   3 | Miejue Shitai |  77 | F     |

|     4 | DingDian   | 32 | M      |       4 |         4 |  4 | Lin Chaoying  |  93 | F     |

+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+

3 rows in set (0.02 sec)

 

MySQL [yuancheng]>

6.2、外联接[外部联接]

    外联接则扩充了内联接的功能,会把内联接中删除表源中的一些保留下来,由于保留下来的行不同,可以将外部联接分为左联接、右联接和完整外联接(全外联接)

6.2.1、左联接

    做联接使用LEFT JOIN进行联接,左联接的结果包括LEFT JOIN子句中指定的左表的所有行,二不仅是联接列所匹配的行。如果左表的某一行在右表中没有匹配行,则在关联的结果行中,来自右表的所有的所有选择列表列均为空值NULL。

       左向联接的语法格式如下:

              SELECT fieldlist FROM table1 left JOIN table2 ON table1.column=table2.column

        参数说明:

            Fieldlist:搜索条件

            table1[INNER] JOIN table2:将table1表与table2表进行外部联接

            table1.column=table2.column:table1表中与table2表中相同的列

 【列6.2.1】查找以左表的为主的数据,查询每个姓名对应的派别

       MySQL [yuancheng]> selectName,Class from students left join classes on students.ClassID=classes.ClassID;

+---------------+----------------+

| Name          | Class          |

+---------------+----------------+

| Shi Zhongyu   | Emei Pai       |

| Shi Potian    | Shaolin Pai    |

| Xie Yanke     | Emei Pai       |

| Ding Dian     | Wudang Pai     |

| Yu Yutong     | QingCheng Pai  |

| Shi Qing      | Riyue Shenjiao |

| Xi Ren        | QingCheng Pai  |

| Lin Daiyu     | Ming Jiao      |

| Ren Yingying  | Lianshan Pai   |

| Yue Lingshan  | QingCheng Pai  |

| Yuan Chengzhi | Lianshan Pai   |

| Wen Qingqing  | Shaolin Pai    |

| Tian Boguang  | Emei Pai       |

| Lu Wushuang   | QingCheng Pai  |

| Duan Yu       | Wudang Pai     |

| Xu Zhu        | Shaolin Pai    |

| Lin Chong     | Wudang Pai     |

| Hua Rong      | Ming Jiao      |

| Xue Baochai   | Lianshan Pai   |

| Diao Chan     | Ming Jiao      |

| Huang Yueying | Lianshan Pai   |

| Xiao Qiao     | Shaolin Pai    |

| Ma Chao       | Wudang Pai     |

| Xu Xian       | NULL           |

| Sun Dasheng   | NULL           |

+---------------+----------------+

25 rows in set (0.03 sec)

 

MySQL [yuancheng]>

      6.2.2、右联接

       右联接使用RIGHT JOIN进行联接,是左联接的反向联接。将返回右表的所有行。如果右表的某一行在左表中没有匹配的行,则将为左表返回空值NULL。

       右联接的语法格式如下:

       SELECT  fieldlistFROM table1 right JOIN table2 ON table1.column=table2.column

        参数说明:

            Fieldlist:搜索条件

            table1[INNER] JOIN table2:将table1表与table2表进行外部联接

            table1.column=table2.column:table1表中与table2表中相同的列

【列6.2.2】通过右联接查询每个姓名对应的派别

       MySQL [yuancheng]> selectName,Class from students right join classes onstudents.ClassID=classes.ClassID;

+---------------+----------------+

| Name          | Class          |

+---------------+----------------+

| Shi Zhongyu   | Emei Pai       |

| Shi Potian    | Shaolin Pai    |

| Xie Yanke     | Emei Pai       |

| Ding Dian     | Wudang Pai     |

| Yu Yutong     | QingCheng Pai  |

| Shi Qing      | Riyue Shenjiao |

| Xi Ren        | QingCheng Pai  |

| Lin Daiyu     | Ming Jiao      |

| Ren Yingying  | Lianshan Pai   |

| Yue Lingshan  | QingCheng Pai  |

| Yuan Chengzhi | Lianshan Pai   |

| Wen Qingqing  | Shaolin Pai    |

| Tian Boguang  | Emei Pai       |

| Lu Wushuang   | QingCheng Pai  |

| Duan Yu       | Wudang Pai     |

| Xu Zhu        | Shaolin Pai    |

| Lin Chong     | Wudang Pai     |

| Hua Rong      | Ming Jiao      |

| Xue Baochai   | Lianshan Pai   |

| Diao Chan     | Ming Jiao      |

| Huang Yueying | Lianshan Pai   |

| Xiao Qiao     | Shaolin Pai    |

| Ma Chao       | Wudang Pai     |

| NULL          | Xiaoyao Pai    |

+---------------+----------------+

24 rows in set (0.03 sec)

 

MySQL [yuancheng]>

      6.2.3、完整联接

       完整联接使用FULL JOIN进行联接,将返回左表和右表中的所有行。当某一行在另一个表中没有匹配行时,另一个表的选择列表将包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。

       完整外联接的语法格式如下:

       SELECT fieldlist FROM table1 fullJOIN table2 ON table1.column=table2.cloumn

6.3、交叉联接

       交叉联接使用CROSS JOIN进行联接,没有WHERE子句的交叉联接将生产联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。

       交叉联接中列和行的数量是这样计算的:

              交叉联接中的列=原表中的列的数量的总和(相加)

              交叉联接中的行=原表中的行数的积(相乘)

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

                     SELECTfieldlist FROM table1 cross JOIN table2

              其中忽略on方法来创建交叉联接。

6.4、联接多表的方法

6.4.1、在WHERE子句中联接多表

              在FROM子句写联接多个表的名称,然后将任意两个表的联接条件分别写在WHERE子句后。

              在WHERE子句中联接多表的语法格式如下:

              SELECT fieldlist FROMtable1,table2,table3…….WHERE table1.column=table2.column and table2.column=table3.column

              【列6.4.1】查找多表的数据通过联接表来查询,(其他方法也查找不出来)

       SELECTorder_info.id,order_info.farmer_id,order_info.land_id,order_info.contact_name,order_info.contact_phone,order_info.service_time_expect,order_info.crop,order_info.fee_predict,order_info.area_predict,order_info.status,order_info.vendor_id, vendor.id,vendor.name,order_info.create_time,land.addressFROM order_info,vendor,land WHERE order_info.vendor_id=vendor.id ANDland.id=order_info.land_id;

6.4.2、在FROM子句中链接多表

              在FROM子句中联接多个表是内部联接的扩展,在FROM子句中联接多表的语法格式如下:

              SELECT fieldlist FROM table1 jointable2 join table3……on table1.column=table2.column andtable2.column=table2.column

       【列6.4.2】通过from子句查询多表中的作物,店铺,作业区域等信息

              MySQL [uav]> SELECTorder_info.crop,order_info.fee_predict,order_info.area_predict,vendor.name,land.addressFROM order_info join vendor join land on order_info.vendor_id=vendor.id ANDland.id=order_info.land_id;

+-----------+-------------+--------------+-----------------------+--------------------------------------------------------------------------------------------------------------+

|crop      | fee_predict | area_predict |name                  | address                                                                                                     |

+-----------+-------------+--------------+-----------------------+--------------------------------------------------------------------------------------------------------------+

|玉米      |      975.00 |        65.00 |州店        |崖城镇附近                                                                                 |

|玉米      |     1560.00 |       104.00 |州店        |国营南滨农场附近                                                                          |

|玉米      |     1800.00 |       120.00 |州店        |国营南滨农场附近

       【列6.4.2】通过from子句查询多表中的作物,店铺,作业区域等信息,并设置别名

       MySQL [uav]> SELECT order_info.crop as农作物,order_info.fee_predict,order_info.area_predict,vendor.nameas 店铺,land.address as 作业低区 FROM order_info join vendor join landon order_info.vendor_id=vendor.id AND land.id=order_info.land_id;

+-----------+-------------+--------------+-----------------------+--------------------------------------------------------------------------------------------------------------+

|农作物    | fee_predict |area_predict | 店铺                  | 作业低区                                                                                                     |

+-----------+-------------+--------------+-----------------------+--------------------------------------------------------------------------------------------------------------+

|玉米      |      975.00 |        65.00 |州店        |城镇附近                                                                                |

|玉米      |     1560.00 |       104.00 |州店        |国营南滨农场附近                                                                           |

|玉米      |     1800.00 |       120.00 |州店        |国营南滨农场附近                                                                          |

|玉米      |     2610.00 |       174.00 |州店        |崖城镇附近                                                                                 |

|玉米      |     2145.00 |       143.00 |州店        |国营南滨农场附近

6.5、UNION合并查询数据记录

       通过关键字UNION来实现并操作,即通过将多个SELECT语句的查询结果合并在以前组成新的关系。

       请注意,UNION内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同

       语法格式如下:

SELECT expression1, expression2,... expression_n

FROM tables

[WHERE conditions]

UNION [ALL | DISTINCT]

SELECT expression1, expression2,... expression_n

FROM tables

[WHERE conditions];

参数

expression1, expression2, ...expression_n: 要检索的列。

tables: 要检索的数据表。

WHERE conditions: 可选,检索条件。

DISTINCT: 可选,删除结果集中重复的数据。默认情况下 UNION 操作符已经删除了重复数据,所以 DISTINCT 修饰符对结果没啥影响。

ALL: 可选,返回所有结果集,包含重复数据

       上述语句中存在多个查询数据记录语句。每个查询数据记录之间使用关键字UNION或UNION ALL进行联接。

6.5.1、带有关键字UNION的合并操作

       关键字UNION会把查询结果集直接合并在一起,同时将会去掉重复数据记录。

【列6.5.1】

       MySQL [yuancheng]> select Name fromstudents union select TID from teachers;

+---------------+

|Name          |

+---------------+

|Shi Zhongyu   |

|Shi Potian    |

|Xie Yanke     |

|Ding Dian     |

|Yu Yutong     |

|Shi Qing      |

|Xi Ren        |

|Lin Daiyu     |

|Ren Yingying  |

|Yue Lingshan  |

|Yuan Chengzhi |

|Wen Qingqing  |

|Tian Boguang  |

|Lu Wushuang   |

|Duan Yu       |

|Xu Zhu        |

|Lin Chong     |

|Hua Rong      |

|Xue Baochai   |

|Diao Chan     |

|Huang Yueying |

|Xiao Qiao     |

|Ma Chao       |

|Xu Xian       |

|Sun Dasheng   |

|1             |

|2             |

|3             |

|4             |

+---------------+

6.5.2、带关键字UNION ALL的合并操作

       关键字UNION ALL会把查询结果直接合并在一起。

MySQL[yuancheng]> select Name from students union all select TID from teachers;

+---------------+

|Name          |

+---------------+

|Shi Zhongyu   |

|Shi Potian    |

|Xie Yanke     |

|Ding Dian     |

|Yu Yutong     |

|Shi Qing      |

|Xi Ren        |

|Lin Daiyu     |

|Ren Yingying  |

|Yue Lingshan  |

|Yuan Chengzhi |

|Wen Qingqing  |

|Tian Boguang  |

|Lu Wushuang   |

|Duan Yu       |

|Xu Zhu        |

|Lin Chong     |

|Hua Rong      |

|Xue Baochai   |

|Diao Chan     |

|Huang Yueying |

|Xiao Qiao     |

|Ma Chao       |

|Xu Xian       |

|Sun Dasheng   |

|1             |

|2             |

|3             |

|4             |

+---------------+

29rows in set (0.02 sec)

 

MySQL[yuancheng]>

6.6、子查询

         在mysql可以通过联接查询实现多表查询数据记录,但却不建议使用,这是因为联接查询的性能很差,因此出现了联接查询替代了子查询,

         所谓的子查询,就是指在一个查询之中嵌套了其他的若干查询,在查询语句嵌套着查询语句,基于某语句的查询结果再次进行的查询,即在一个select查询语句的WHERE或FROM子句中包含另一个SELECT查询语句。在查询语句中,外层SELECT查询语句称为主查询,WHERE子句中的SELECT查询语句被称为子查询,也被称为嵌套查询。

         通过子查询可以实现多表查询,该查询语句中可能包含IN、ANY、ALL和EXISTS等关键字,除此之外还可能包含比较运算符。理论上子查询可以出现在查询语句的任意位置,但是在实际中,子查询经常出现在WHERE和FROM子句中。

         WHERE子句中的子查询:该位置处的子查询一般返回单行单列、多行多列数据记录。如:

         主要用于比较表达式中的子查询,子查询仅能返回单个值

         用于IN中的子查询:子查询应该单键查询并返回一个或多个值从构成列表。

         用于EXISTS

         FROM子句中的子查询:该位置处的子查询一般返回多行多列数据记录,可以当作一张临时表

6.6.1、返回结果为单行单列和单行多列子查询

       当子查询的返回结果为单行单列数据记录时,该子查询语句一般在主查询语句的WHERE子句里,通常会包含比较运算符符号(>、<、=、!=等)

【列6.6.1】查询Age大于45的所有数据

MySQL [yuancheng]> select * fromteachers where Age > (select Age from teachers where Age=45);

+-----+---------------+-----+--------+

| TID | Name          | Age | Gender |

+-----+---------------+-----+--------+

|  2 | Zhang Sanfeng |  94 | M      |

|  3 | Miejue Shitai |  77 | F      |

|  4 | Lin Chaoying  |  93 | F     |

+-----+---------------+-----+--------+

3 rows in set (0.03 sec)

 

MySQL [yuancheng]>

6.6.2、单行多列子查询

       WHERE子句中的子查询除了是返回单行单列的数据记录外,还可以是返回单行多列的数据记录,不过这种子查询很少出现。

 

6.6.3、返回结果为多行单列子查询

       当子查询的返回结果为多行单列数据记录时,该子查询语句一般会在主查询语句的WHERE子句里出现,通常会包含IN、ANY、ALL、EXISTS等关键字。

 未完待续。。。。。


你可能感兴趣的:(ARM/Linux/Unix)