MySQL联表查询的简单示例

MySql会用到联表查询,对于刚学习的新手来说,可能会理解起来有难度。下面这篇文章就来给大家详细介绍MySQL联表查询的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

关系型数据库,免不了表之间存在各种引用与关联。这些关联是通过主键与外键搭配来形成的。所以,取数据时,很大情况下单张表无法满足需求,额外的数据则需要将其他表加入到查询中来,这便是 JOIN 关键字完成的操作。

  • MySQL 中 JOIN, CROSS JOIN 和 INNER JOIN 三者语法功能上相同,可互换,而 SQL 标准中,INNER JOIN 需要搭配 ON 语句。

多表联合查询时,可省略 JOIN 关键字,以逗号分隔多张表,此时默认会当作 INNER JOIN 来处理。比如,

SELECT table1.*,
  table2.*
FROM table1,
  table2; 

等效于:

SELECT table1.*,
  table2.*
FROM table1
  INNER JOIN table2; 
  • 但这种通过逗号隐式指定的联表形式其优先级要低于直接通过关键字(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 呈现。
SELECT left_tbl.*
 FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
 WHERE right_tbl.id IS NULL;

通过此方法可方便地过滤出右边表中不符合条件的记录。

  • 联表查询时可为每张参与进来的表指定别名,方便在其他表达式中引用。两种方式,一个是通过 AS 关键字 tbl_name AS alias_name,另一种是直接在表名后面跟上别名,tbl_name alias_name。
SELECT t1.name, t2.salary
 FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;

SELECT t1.name, t2.salary
 FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
  • 一条查询语句中的子查询必需取一个别名,这样才能在其他表达式中引用。
SELECT * FROM (SELECT 1, 2, 3) AS t1;
  • USING(join_column_list) 语句指定两个表中均包含的列,查询时只针对这里指定的列进行比较。
a LEFT JOIN b USING (c1, c2, c3)
  • NATURAL [LEFT] JOIN 与 INNER JOIN 和 LEFT JOIN 配合使用了 USING 指定表中所有列的情况等效。
  • RIGHT JOIN 与 LEFT JOIN 类似,只是最终结果是依据右边表,将左边表中不符合的在结果中以 NULL 呈现。为了方便在不同数据库间迁移,推荐始终使用 LEFT JOIN。

一些 JOIN 示例:

SELECT * FROM table1, table2;

SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;

SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;

SELECT * FROM table1 LEFT JOIN table2 USING (id);

SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
 LEFT JOIN table3 ON table2.id = table3.id;
  • NATURAL JOIN 的结果中不会有重复的列。因为其与 USING 雷同,所以 USING 时也没有复杂的列。

考察下面的示例:

CREATE TABLE t1 (i INT, j INT);
CREATE TABLE t2 (k INT, j INT);
INSERT INTO t1 VALUES(1, 1);
INSERT INTO t2 VALUES(1, 1);
SELECT * FROM t1 NATURAL JOIN t2;
SELECT * FROM t1 JOIN t2 USING (j);

查询结果:

+------+------+------+
| j    | i    | k    |
+------+------+------+
|    1 |    1 |    1 |
+------+------+------+
+------+------+------+
| j    | i    | k    |
+------+------+------+
|    1 |    1 |    1 |
+------+------+------+

结果中同名的列只出现一次,且都是值相同的那些记录。

通过向两表中插入一条新记录,令它们的 j 不相同,再进行测试。

mysql> INSERT INTO t1 VALUES(2, 2);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO t2 VALUES(2, 3);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1 natural join t2;
+------+------+------+
| j | i | k |
+------+------+------+
| 2 | 2 | 1 |
+------+------+------+
1 row in set (0.00 sec)
  • USING 和 ON 作为条件时其他限制的联合条件是一样的,可互相转换。但在 SELECT * 返回结果时,还是有差异的。前者只在 USING 中指定的列中返回合并后的结果,后者则针对的是表中所有列。
a LEFT JOIN b USING (c1, c2, c3)
a LEFT JOIN b ON a.c1 = b.c1 AND a.c2 = b.c2 AND a.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)中的表。

CREATE TABLE t1 (i1 INT);
CREATE TABLE t2 (i2 INT);
CREATE TABLE t3 (i3 INT);

针对上面的表,以下查询会报错:

mysql> SELECT * FROM t1 JOIN t2 ON (i1 = i3) JOIN t3;
ERROR 1054 (42S22): Unknown column 'i3' in 'on clause'

而以下查询则可以:

mysql> SELECT * FROM t1 JOIN t2 JOIN t3 ON (i1 = i3);
Empty set (0.00 sec)

因为此时 t3 在 ON 语句的操作范围内了。

相关资源

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • mysql删除关联表的实操方法

    mysql数据库中,表与表之间进行关联之后,就不可随意的进行删除操作,否则会影响所有关联表之间的结构,那么如何安全的删除关联表呢,让我们来了解一下. 删除表的外键约束 外键是一个特殊字段,其将某一个表与其父表建立关联关系.在创建表的时候,外键约束就已经设定好了.去掉他们之间的关联关系需要用到下面语句. alter table 表名 drop foreign key 外键别名: 外键别名参数指创建表时设置的外键代号. 2.删除没有被关联的普通表 drop table 表名: 删除一个表时,表中的所

  • MySQL中联表更新与删除的语法介绍

    前言 相信大家在日常使用mysql,可能会遇到需要同时更新两张表时,我会采用在同一个事务中使用2句sql语句分别进行更新.其实,这种需要发送2句sql语句的方法效率相对来说是比较低的,有没有只用1句sql语句就可以完成这个操作的呢? 答案是有的,下面将是代码记录: 假设有2张表: 1,user表,字段为:id,user_name 2,user_role表,字段为:id,role_name,user_id 关联关系是 user.id = user_role.user_id 现要更改某一条user表

  • mysql 行列动态转换的实现(列联表,交叉表)

    (1)动态,适用于列不确定情况 create table table_name( id int primary key, col1 char(2), col2 char(2), col3 int ); insert into table_name values (1 ,'A1','B1',9), (2 ,'A2','B1',7), (3 ,'A3','B1',4), (4 ,'A4','B1',2), (5 ,'A1','B2',2), (6 ,'A2','B2',9), (7 ,'A3','B

  • mysql嵌套查询和联表查询优化方法

    嵌套查询糟糕的优化在上面我提到过,不考虑特殊的情况,联表查询要比嵌套查询更有效.尽管两条查询表达的是同样的意思,尽管你的计划是告诉服务器要做什么,然后让它决定怎么做,但有时候你非得告诉它改怎么做.否则优化器可能会做傻事.我最近就碰到这样的情况.这几个表是三层分级关系:category, subcategory和item.有几千条记录在category表,几百条记录在subcategory表,以及几百万条在item表.你可以忽略category表了,我只是交代一下背景,以下查询语句都不涉及到它.这

  • MySQL联表查询的简单示例

    MySql会用到联表查询,对于刚学习的新手来说,可能会理解起来有难度.下面这篇文章就来给大家详细介绍MySQL联表查询的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 关系型数据库,免不了表之间存在各种引用与关联.这些关联是通过主键与外键搭配来形成的.所以,取数据时,很大情况下单张表无法满足需求,额外的数据则需要将其他表加入到查询中来,这便是 JOIN 关键字完成的操作. MySQL 中 JOIN, CROSS JOIN 和 INNER JOIN 三者语法功能上相同,可

  • MySQL联表查询基本操作之left-join常见的坑

    概述 对于中小体量的项目而言,联表查询是再常见不过的操作了,尤其是在做报表的时候.然而校对数据的时候,您发现坑了吗?本篇文章就 mysql 常用联表查询复现常见的坑. 基础环境 建表语句 DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `role_name` VARCHAR(50) DEFAULT NULL COMMENT '角色名', PRIMARY KEY (`i

  • Mysql联表update数据的示例详解

    1.MySQL UPDATE JOIN语法 在MySQL中,可以在 UPDATE语句 中使用JOIN子句执行跨表更新.MySQL UPDATE JOIN的语法如下: UPDATE T1, T2, [INNER JOIN | LEFT JOIN] T1 ON T1.C1 = T2. C1 SET T1.C2 = T2.C2, T2.C3 = expr WHERE condition 更详细地看看MySQL UPDATE JOIN语法: 首先,在UPDATE子句之后,指定主表(T1)和希望主表连接表

  • MySQL连表查询分组去重的实现示例

    目录 业务逻辑 数据表结构 查询逻辑 SQL脚本 脚本说明 业务逻辑 通过多种渠道将小程序的活动页链接发布出去,比如通过多多种短信附带链接( channel 就记为 sms1,sms2,sms3 ),或者海报上面贴微信小程序的二维码( channel 记为 qrcode1,qrcode2,qrcode3 ),线下会员通过扫描二维码也能进入小程序指定的活动页,亦或者是通过其他会员分享的小程序链接也可以进入小程序( channel 记为 share).这些不同的进入方式在我这篇文章统称为不同的渠道,

  • MySQL派生表联表查询实战过程

    目录 前情提要: 查询过程: 总结: 前情提要: 公司运营的一个商城系统,忽然发现订单提现功能有问题,有大量的商户体现金额和订单金额不一致.于是产生了需求,需要把提现表和供应商表作为一个结果集,连接上订单表中的订单金额,通过计算订单表的金额和体现表商户提现的金额进行比对,查看商户是多提现了还是少提现了. 下面记录我的查询过程. 查询过程: 刚开始,第一步我以提现表为主表,查询出来相关结果.MySQL语句如下 SELECT count(ysw.supply_id) AS '提现次数',ysw.us

  • mongodb实现同库联表查询方法示例

    前言 最近在工作中遇到一个问题,需要对mongodb数据库进行联表查询操作,发现网上这方面的资料较少,无奈只能自己来实现了,下面话不多说了,来一起看看详细的介绍: 注意:这里只对同库联表查询做介绍,跨库联表查询可能在之后也会介绍(因为公司架构变动,之后可能会联表查询) 我用到的联表查询有两种,一种是mongoose的populate,一种是$lookup 一.populate populate是使用外键关联子表 例如现在有一张订单表结构(动态外键): var orderSchema = new

  • MySQL多表查询详解下

    好好吃饭,好好休息,听着很简单,实际落实缺失不那么容易. 继续回顾MySql的多表查询之1999语法 #二,SQL1999语法 语法: SELECT 查询列表 FROM 表1 别名 [连接类型] JOIN 表2 别名 ON 链接条件 [WHERE 筛选条件] [GROUP BY 分组] [HAVING 筛选条件] [ORDER BY 排序列表ASC|DESC] 分类(连接类型): 内连接(★): INNER 外联结 左外(★):LEFT [OUTER] 右外(★):RIGHT [OUTER] 全

  • MyBatis-Plus联表查询(Mybatis-Plus-Join)的功能实现

    目录 引入依赖 数据准备 修改Mapper 查询 分页查询 最后 mybatis-plus作为mybatis的增强工具,简化了开发中的数据库操作.一旦遇到left join或right join的左右连接,还是得老老实实的打开xml文件,手写上一大段的sql语句.今天总结一下一款叫做mybatis-plus-join的工具(后面就简称mpj了),可以用类似mybatis-plus中QueryWrapper的方式来进行联表查询. 引入依赖 首先在项目中引入引入依赖坐标,因为mpj中依赖较高版本my

  • MySQL单表查询操作实例详解【语法、约束、分组、聚合、过滤、排序等】

    本文实例讲述了MySQL单表查询操作.分享给大家供大家参考,具体如下: 语法 一.单表查询的语法 SELECT 字段1,字段2... FROM 表名                   WHERE 条件                   GROUP BY field                   HAVING 筛选                   ORDER BY field                   LIMIT 限制条数 二.关键字的执行优先级(重点) 重点中的重点:关键

  • MySQL多表查询详解上

    时光在不经意间,总是过得出奇的快.小暑已过,进入中暑,太阳更加热烈的绽放着ta的光芒,...在外面被太阳照顾的人们啊,你们都是勤劳与可爱的人啊.在房子里已各种姿势看我这篇这章的你,既然点了进来,那就由我继续带你回顾MySql的知识吧! 回顾练习资料girls库以及两张表的脚本: 链接: https://pan.baidu.com/s/1bgFrP7dBBwk3Ao755pU4Qg 提取码: ihg7 引题:笛卡尔现象,先来观看一下两张表. SELECT * FROM boys; SELECT *

随机推荐