联接查询是又笛卡尔乘积运算再加一个选取运算构成的查询。首先用笛卡尔乘积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,确保只把分别来自两个数据集合并且有重叠部分的行合并在一起。联接的全部意义在于水平方向上合并两个数据集合,并产生一个新的结果集合。
联接条件可在FROM或WHERE子句中指定,建议在FROM子句中指定联接条件。WHERE和HAVING子句还可以包含搜索条件,以进一步筛选根据联接条件选择的行。
联接可以分为内部联接(INNERJOIN)、外部联接(OUTER JOIN)和交叉联接(CROSS JOIN)3种。
内联接是使用比较运算符比较要联接列中的值的联接,内联接也叫联接。可以分为:
等值联接:让表之间的字段以“等值”建立联接关系
不等值联接:让表之间的字段以“不等值”建立联接关系
自然联接:同一张表自己和自己联接
内联接使用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】
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】 查找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]>
外联接则扩充了内联接的功能,会把内联接中删除表源中的一些保留下来,由于保留下来的行不同,可以将外部联接分为左联接、右联接和完整外联接(全外联接)
做联接使用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]>
右联接使用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]>
完整联接使用FULL JOIN进行联接,将返回左表和右表中的所有行。当某一行在另一个表中没有匹配行时,另一个表的选择列表将包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
完整外联接的语法格式如下:
SELECT fieldlist FROM table1 fullJOIN table2 ON table1.column=table2.cloumn
交叉联接使用CROSS JOIN进行联接,没有WHERE子句的交叉联接将生产联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。
交叉联接中列和行的数量是这样计算的:
交叉联接中的列=原表中的列的数量的总和(相加)
交叉联接中的行=原表中的行数的积(相乘)
交叉联接的语法格式如下:
SELECTfieldlist FROM table1 cross JOIN table2
其中忽略on方法来创建交叉联接。
在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;
在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 |州店 |国营南滨农场附近
通过关键字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进行联接。
关键字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 |
+---------------+
关键字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]>
在mysql可以通过联接查询实现多表查询数据记录,但却不建议使用,这是因为联接查询的性能很差,因此出现了联接查询替代了子查询,
所谓的子查询,就是指在一个查询之中嵌套了其他的若干查询,在查询语句嵌套着查询语句,基于某语句的查询结果再次进行的查询,即在一个select查询语句的WHERE或FROM子句中包含另一个SELECT查询语句。在查询语句中,外层SELECT查询语句称为主查询,WHERE子句中的SELECT查询语句被称为子查询,也被称为嵌套查询。
通过子查询可以实现多表查询,该查询语句中可能包含IN、ANY、ALL和EXISTS等关键字,除此之外还可能包含比较运算符。理论上子查询可以出现在查询语句的任意位置,但是在实际中,子查询经常出现在WHERE和FROM子句中。
WHERE子句中的子查询:该位置处的子查询一般返回单行单列、多行多列数据记录。如:
主要用于比较表达式中的子查询,子查询仅能返回单个值
用于IN中的子查询:子查询应该单键查询并返回一个或多个值从构成列表。
用于EXISTS
FROM子句中的子查询:该位置处的子查询一般返回多行多列数据记录,可以当作一张临时表
当子查询的返回结果为单行单列数据记录时,该子查询语句一般在主查询语句的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]>
WHERE子句中的子查询除了是返回单行单列的数据记录外,还可以是返回单行多列的数据记录,不过这种子查询很少出现。
当子查询的返回结果为多行单列数据记录时,该子查询语句一般会在主查询语句的WHERE子句里出现,通常会包含IN、ANY、ALL、EXISTS等关键字。
未完待续。。。。。