论SQL语句中的多表关系
- 无论条件是否为True,都将返回左表格式
- 其中如果条件为True,那么将右表数据挂载,否则右表数据设为null
- Join体系中,on类似于where
以前,被子查询这种语句弄得超迷糊,然后在交大的学习平台上发现原来很多情况都不需要子查询,直接一个where就搞定了,但是并不了解哪些对应关系。
前几天在网上看到一个大神写的SQL,冒出了一个特别神奇的语法:Left join,当时懵了,这是啥?花了好长时间的研究,终于搞清楚了啥是外链接。
但是啊,不知道其他初学者有没有这种感受:看网上哪些例子是非常懂的,然而自己用在项目中,思维却卡机了。无奈之下,我还是继续研究了哪位大神的源码,如下:
SELECT r.roleid,r.rolename,r.deptid,d.deptname,GROUP_CONCAT(m.menuname SEPARATOR ',' ) menuname
FROM js_role r
LEFT JOIN js_role_menu rm ON r.roleid = rm.roleid
LEFT JOIN js_menu m ON m.menuid = rm.menuid
LEFT JOIN js_dept d ON d.deptid = r.deptid
GROUP BY r.roleid
注:GROUP_CONCAT(m.menuname SEPARATOR ‘,’ ) – 表示:按组,合并列表中的menuname字段并以’,’分隔
当时要查的四张表,分别是部门表,角色表,角色_菜单表和菜单表,要查出每个角色的权限,以及部门名称。
附上表的数据:
js_role表(角色表)
roleid rolename deptid 1 超级管理员 1 2 运营主管 2 3 运营员 2
js_role_menu(角色对应菜单表)
roleid menuid 1 1 3 1 2 2 2 3 3 2 1 3
js_menu(菜单表)
menuname menuid 系统管理 1 用户管理 2 菜单管理 3
js_dept(部门表)
deptid deptname 1 总部 2 运营部 3 财务部
角色_菜单表就相当于权限表,存放的是角色的id和授权菜单的id。
然后当时写了一个SQL:
SELECT r.roleid,r.rolename,r.deptid,d.deptname,
GROUP_CONCAT(m.menuname SEPARATOR ',') menuname
FROM
js_dept d,js_role r,js_role_menu rm,js_menu m
WHERE d.deptid = r.deptid
AND rm.roleid = r.roleid
AND m.menuid = rm.menuid
GROUP BY r.roleid
还是相当轻松的,然后我就结合了两种方法去对比理解了。
首先主表为js_role,第一个Left join,将js_role_model添加至末尾,同理,第三个第四个表都被join到了主表上面,至group by之前,其实这个表大概的样子就是
表名 | |||
---|---|---|---|
js_role表 | js_role_menu表 | js_menu表 | js_user表 |
有没有发现用Where写SQL语句中的FROM和这张表是完全对应的,而其他的关键字比如Join中的on对应的就是where … and … ,对应了关系拆解开来就很容易理解了。
因为这个例子里都是用XXXid来做条件筛选,id不可能为空,所以如果执行途中有一条没有对应,那么它之后连接上的所有表内容全都为null,符合开发的要求(Shiro框架)。
好了,来总结一下left join的效果:
- 无论条件是否为True,都将返回左表格式
- 其中如果条件为True,那么将右表数据挂载,否则右表数据设为null
- Join体系中,on类似于where
PS:第一次发表博客,欢迎大家提出宝贵的意见哟~