在面试的时候曾3次踩过了sql join的坑,第一次是校招面试的时候,面的是国内某大行的开发岗,被问到会不会使用sql join,当时直接回答的是不会,只会使用简单的sql操作。第二次面试的是另一大行的测试岗,人家直接问的是left join和right join的区别,这次我事先做了准备吧,说left join查询会显示左表的全部内容,right join会显示右表的全部内容。ok,勉强过关,面试官也没再继续追问下去,如果他继续追问下去我一定原形毕露。两年多过去了,博主从事了QA(Quality Analyist)的工作,每天都在专研怎么写测试用例、怎么实施质量内建、怎么搞自动化测试,平时项目中会用到简单的sql查数据库,之前面试的痛并没有引起我的重视,毕竟第二次我算是敷衍过了。谁曾想到,还有第三次!公司内部为了员工的发展考虑,可以根据自我意愿换业务线,换之前会有一个简单的面试。
面试的同事看了看我的简历说:看你会sql呀?
我:是的,会一些简单的。(不详的预感瞬间飙升)
面试同事:那你知道sql join的一些操作吗?比如inner join。
我:知道一些left join、right join的操作,inner join不清楚。(你看,这像是一个用过join操作的人的回答吗?!)
面试同事:好,那你说一下她们是干嘛的呢?
我:left join查询会显示左表的全部内容,right join会显示右表的全部内容(强撑!)
面试同事:(他真的露出了吃惊的表情),说看来你没有真正理解它们的用法呀。
我:嗯嗯是呢,平时没怎么用。(内心os:饶了我吧,我不该强撑说知道的,早点投降不香吗?)
面试同事:888888开始给我讲它们的用法。。。
所以,我痛下决心,要学一下这几个join的用法,发誓不在同一个地方跌倒4次。
安装mysql/oracle
可参考:https://blog.csdn.net/qq_37924224/article/details/105288363
创建user表、orders表和order_items表并插入数据,如下图:
可参考:https://blog.csdn.net/qq_37924224/article/details/105510809
4. 理解join的含义
join的意思是连接,对于数据库来说,就是连接两个或以上的表。当什么时候需要连接查询两个表呢?当一个表中的内容不足以表达你需要的内容,而另一个与之相关联的表恰好有你所需的信息。所以join查询的目的就是补充你查询的表中没有的内容。那怎么样将两个表关联起来呢?就需要两个表有相同的字段,即primary key和foreign key。
inner join/join级联查询两个表时,返回的结果是两个表中均存的记录,可以理解是与关系。如下图所示:
下面是实际的例子。
select user.user_id,
user.user_name,
user.user_alias,
user.email,
user.city,
orders.order_id,
orders.create_date,
orders.update_date
from user
inner join orders on user.user_id = orders.user_id
order by user.user_id;
那如果是3张表呢,又该怎么查询?
select user.user_id,
user.user_name,
orders.order_id,
order_items.item_id,
order_items.item_name
from user
inner join orders on user.user_id = orders.user_id
inner join order_items on orders.order_id = order_items.order_id
order by user.user_id;
left join级联查询两个表时,会返回的左表的所有记录以及右表存在的记录,没有则返回null。如下图所示:
select user.user_id,
user.user_name,
orders.order_id,
orders.create_date,
orders.update_date
from user
left join orders on user.user_id = orders.user_id
order by user.user_id;
select user.user_id,
user.user_name,
orders.order_id,
order_items.item_id,
order_items.item_name
from user
left join orders on user.user_id = orders.user_id
left join order_items on orders.order_id = order_items.order_id
order by user.user_id;
right join级联查询两个表时,会返回的右表的所有记录以及左表存在的记录,没有则返回null。如下图所示:
select orders.order_id,
user.user_id,
user.user_name,
user.user_alias,
user.city,
user.email
from user
right join orders on user.user_id = orders.user_id
order by orders.order_id;
select orders.order_id,
user.user_id,
user.user_name,
user.user_alias,
user.city,
user.email,
order_items.order_id,
order_items.item_name
from user
right join orders on user.user_id = orders.user_id
right join order_items on orders.order_id = order_items.order_id
order by orders.order_id;
full join级联查询两个表时,会返回的两个表中所有的记录,没有则返回null。如下图所示:
由于mysql不支持full join,所以这里就不做full join的演示了。不过我们可以使用left join和right join来达到full join的目的。
select *
from user
left join orders on user.user_id = orders.user_id
union
select *
from user
right join orders on user.user_id = orders.user_id order by user_name;