一、如下SQL1
SELECT i.*,su1.name as createName,su2.name as updateNameFROM information ileft join sys_user su1 on su1.id=i.create_idleft join sys_user su2 on su2.id=i.update_id
二、分析
1、SELECT i.*,su.name as createName,sua.name as updateName:
这部分选择了information表的所有列(i.*),以及两个左连接的结果中的name字段。
2、left join sys_user su1 on su1.id=i.create_id:
这是一个左连接,它会将information表中的每一行与sys_user表中id等于information表中create_id的行匹配。如果create_id在information表中没有对应的值(即没有创建用户),那么这个字段的值就是NULL,这就是左连接,不会丢弃那些没有匹配的数据。
3、left join sys_user su2 on su2.id=i.update_id:
同样,这又做了一个左连接,将information表中的每一行与sys_user表中id等于information表中update_id的行匹配,用于获取修改用户的姓名。
三、如下SQL2
WITH RECURSIVE ParentHierarchy AS (SELECT id, user_id, parent_idFROM eWHERE user_id = #{userId}UNION ALLSELECT e.id, e.user_id, e.parent_idFROM eINNER JOIN ParentHierarchy ph
ON e.id = ph.parent_id)SELECT *FROM ParentHierarchyWHERE parent_id = 0;
1、WITH RECURSIVE ParentHierarchy AS (...):这部分定义了一个递归的公用表表达式(CTE),名为ParentHierarchy 。
2、SELECT id, user_id, parent_id FROM e WHERE user_id = #{userId}:这是递归的初始查询部分,即递归的基准条件,它从表e中选择那些user_id字段等于指定userId的记录,这些记录就是层级结构的起始点。
3、UNION ALL:这个关键字用来将初始查询的结果和后续递归查询的结果合并在一起。(与union1不同,可能有重复记录)
4、SELECT e.id, e.user_id, e.parent_id FROM e INNER JOIN ParentHierarchy ph ON e.id = ph.parent_id:这是递归的主体部分,它将表e与已经构建的ParentHierarchy进行内连接,匹配e表中的id和ParentHierarchy中的parent_id,从而得到下一级的层级数据。
5、SELECT * FROM ParentHierarchy WHERE parent_id = 0:这是最终的查询语句,它从递归构建的层级结构中选出所有parent_id为0的记录。这里的0通常用作顶级父级的标志,意味着选出的是最顶层的记录。
举例说明:表e
1、第一步
user_id=15
初始PH (6,3,15)
e表
inner join 它会返回两个表中字段匹配的行 ph.parent_id=e.id
结果集
(1,0,10)
2、第二步
选出所有parent_id为0的记录
结果
(1,0,10)
四、思考
什么时候此递归会返回null值?