首页 > 技术分享 > MySQL
收藏

MySQL连表查询实用技巧

07/08 16:06
大潇博客 原创文章,转载请标明出处

一、MySQL内关联(自关联)

当有这样的需求,对同一张表进行不同条件连续查询时(例如不同条件的group by),需要用到INNER JOIN内连接,也就是自关联。


举例说明,例如有下面这两张表,一张试题表,一张分类表(为简单理解,每个表只有两三个字段)

试题表:

create table question(

id int primary key auto_increment,  /*主键*/

name varchar(255) NOT NULL,        /*试题名称*/

difficult varchar(64) NOT NULL,      /*题难度*/

class_id int NOT NULL                     /*分类id*/

);

分类表:

create table class(

id int primary key auto_increment,  /*分类id 主键*/

title varchar(255) NOT NULL            /*分类名称*/

attribute varchar(128) NOT NULL    /*属性*/

);


试题表插入数据:

insert into question(name,difficult,class_id) values('这是一道题','3','1001');

insert into question(name,difficult,class_id) values('这是一道题','3','1002');

1001.png


分类表插入数据:

insert into class(id,title,attribute) values(1001,'数学题','中学奥数题型');

insert into class(id,title,attribute) values(1002,'逻辑题','思维培养题型');

1002.png


现在需要根据试题分类id,查询同名称题所属所有分类的名称(注释:可能有相同名称的题,归属不用的分类),已知条件只有一个题分类class_id = '1001'


传统最简单的方法是,查询两次数据库,第一次通过题id查出题名称,第二次通过题名称查出所有id,并关联分类表查出分类名称。

1、SELECT NAME FROM question WHERE class_id = '1001';

2、SELECT cs.title FROM question qs LEFT JOIN class cs ON qs.class_id = cs.id WHERE qs.name = '上条语句查询的name';


上文做法做通俗易懂,但是会增加一次数据库的连接,同时增加逻辑处理代码,若要用一条SQL语句查询出结果,INNER JOIN自关联为最佳,如下语句:

SELECT question_1st.name,class.title FROM question question_1st INNER JOIN (SELECT NAME FROM question WHERE class_id = 1001) question_2nd ON question_1st.name = question_2nd.name LEFT JOIN class class ON question_1st.class_id = class.id;



二、MySQL左右关联

我们最常使用的左关联,就是两张表通过LEFT JOIN连接起来,后面带有WHERE条件,如此一来SQL语句即完成,这种SQL简单写法初学者就可以轻松搞定。


举例说明:比如上面两张表,已知题的名称“这是一道题”和分类名称“数学题”,根据这两个条件查询题的难度和分类属性。


大部分人可能会这样写SQL语句:

select qs.*,cs.title from question qs left join class cs on qs.class_id = cs.id where qs.name = "这是一道题" and cs.title = "数学题";

1003.png

这种语句在理想状态下是没问题的,为什么说是理想状态,就是指两张表中的数据皆满足WHERE后面的条件。


但若是WHERE中的个条件在其中一张数据表中没有(不满足),那后面查询到的结果便是空,这样做在实际应用中便埋下隐患。


假设题的名称不变,分类名称变为“英语题”,这个分类在上面添加数据时是没有的,我们来实际试一下。

select * from question qs left join class cs on qs.class_id = cs.id where qs.name = "这是一道题" and cs.title = "英语题";

4.png


怎样解决,在连表查询时换一种写法就可以巧妙避免BUG的发生,仔细读下面的SQL语句

select qs.*,cs.title from question qs left join (select * from class where title = "数学题") cs on qs.class_id = cs.id where qs.name = "这是一道题";

1004.png


注:因为要查询的题难度在question表中,我们首先查询了question表,所以实用left join,查出的数据是左表的全部,右表没有的数据显示NULL值。反之则用right join进行关联查询。


打赏

阅读排行

大家都在搜

博客维护不易,感谢你的肯定
扫码打赏,建议金额1-10元
  • 15601023311