如何在MySQL中实现联表查询
这篇文章将为大家详细讲解有关如何在MySQL中实现联表查询,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
MySQL 中 JOIN, CROSS JOIN 和 INNER JOIN 三者语法功能上相同,可互换,而 SQL 标准中,INNER JOIN 需要搭配 ON 语句。
多表联合查询时,可省略 JOIN 关键字,以逗号分隔多张表,此时默认会当作 INNER JOIN 来处理。比如,
SELECTtable1.*,table2.*FROMtable1,table2;
等效于:
SELECTtable1.*,table2.*FROMtable1INNERJOINtable2;
但这种通过逗号隐式指定的联表形式其优先级要低于直接通过关键字(INNER JOIN, CROSS JOIN, LEFT JOIN)指定的形式。所以 t1, t2 JOIN t3 会被解析成 (t1, (t2 JOIN t3)) 而不是 ((t1, t2) JOIN t3)
需要注意的是,当逗号形式与其他联表关键词结合时,在指定了联表条件,比如通过 ON 条件时,会报错。
ON 指定的联表条件其语法同 WHERE,所有后者可接受的表达式都可用于 ON。两者看起来功能上雷同,ON 一般用于指定联表条件,即表之间怎么被联合,而 WHERE 则用于过滤结果。
LEFT JOIN 时,右边表中不满足 ON 或 USING 指定的条件时,会在结果中以 NULL 呈现。
SELECTleft_tbl.*FROMleft_tblLEFTJOINright_tblONleft_tbl.id=right_tbl.idWHEREright_tbl.idISNULL;
通过此方法可方便地过滤出右边表中不符合条件的记录。
联表查询时可为每张参与进来的表指定别名,方便在其他表达式中引用。两种方式,一个是通过 AS 关键字 tbl_name AS alias_name,另一种是直接在表名后面跟上别名,tbl_name alias_name。
SELECTt1.name,t2.salaryFROMemployeeASt1INNERJOINinfoASt2ONt1.name=t2.name;SELECTt1.name,t2.salaryFROMemployeet1INNERJOINinfot2ONt1.name=t2.name;
一条查询语句中的子查询必需取一个别名,这样才能在其他表达式中引用。
SELECT*FROM(SELECT1,2,3)ASt1;
USING(join_column_list) 语句指定两个表中均包含的列,查询时只针对这里指定的列进行比较。
aLEFTJOINbUSING(c1,c2,c3)
NATURAL [LEFT] JOIN 与 INNER JOIN 和 LEFT JOIN 配合使用了 USING 指定表中所有列的情况等效。
RIGHT JOIN 与 LEFT JOIN 类似,只是最终结果是依据右边表,将左边表中不符合的在结果中以 NULL 呈现。为了方便在不同数据库间迁移,推荐始终使用 LEFT JOIN。
一些 JOIN 示例:
SELECT*FROMtable1,table2;SELECT*FROMtable1INNERJOINtable2ONtable1.id=table2.id;SELECT*FROMtable1LEFTJOINtable2ONtable1.id=table2.id;SELECT*FROMtable1LEFTJOINtable2USING(id);SELECT*FROMtable1LEFTJOINtable2ONtable1.id=table2.idLEFTJOINtable3ONtable2.id=table3.id;
NATURAL JOIN 的结果中不会有重复的列。因为其与 USING 雷同,所以 USING 时也没有复杂的列。
考察下面的示例:
CREATETABLEt1(iINT,jINT);CREATETABLEt2(kINT,jINT);INSERTINTOt1VALUES(1,1);INSERTINTOt2VALUES(1,1);SELECT*FROMt1NATURALJOINt2;SELECT*FROMt1JOINt2USING(j);
查询结果:
+------+------+------+
| j | i | k |
+------+------+------+
| 1 | 1 | 1 |
+------+------+------+
+------+------+------+
| j | i | k |
+------+------+------+
| 1 | 1 | 1 |
+------+------+------+
结果中同名的列只出现一次,且都是值相同的那些记录。
通过向两表中插入一条新记录,令它们的 j 不相同,再进行测试。
mysql>INSERTINTOt1VALUES(2,2);QueryOK,1rowaffected(0.00sec)mysql>INSERTINTOt2VALUES(2,3);QueryOK,1rowaffected(0.00sec)mysql>select*fromt1naturaljoint2;+------+------+------+|j|i|k|+------+------+------+|2|2|1|+------+------+------+1rowinset(0.00sec)
USING 和 ON 作为条件时其他限制的联合条件是一样的,可互相转换。但在 SELECT * 返回结果时,还是有差异的。前者只在 USING 中指定的列中返回合并后的结果,后者则针对的是表中所有列。
aLEFTJOINbUSING(c1,c2,c3)aLEFTJOINbONa.c1=b.c1ANDa.c2=b.c2ANDa.c3=b.c3
USING 情况下的返回:
COALESCE(a.c1,b.c1),COALESCE(a.c2,b.c2),COALESCE(a.c3,b.c3)
ON 的返回:
a.c1, a.c2, a.c3, b.c1, b.c2, b.c3
ON 语句中只能引用其操作表(operands)中的表。
CREATETABLEt1(i1INT);CREATETABLEt2(i2INT);CREATETABLEt3(i3INT);
针对上面的表,以下查询会报错:
mysql>SELECT*FROMt1JOINt2ON(i1=i3)JOINt3;ERROR1054(42S22):Unknowncolumn'i3'in'onclause'
而以下查询则可以:
mysql>SELECT*FROMt1JOINt2JOINt3ON(i1=i3);Emptyset(0.00sec)
关于如何在MySQL中实现联表查询就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。