用纯sql方式实现判断数值,去查询不同的表。外加树节点查询扩展

提前首先说明一下,这篇文章单纯的是做记录用,方便以后自己查看。如有任何问题,概不解答,因为我没遇到。我对sql这一块也不是了解得很好。

首先说一下遇到的需求:

实际需求是这样的,用户与管理员表是不同的,然后评论表里有一个user_id字段和一个is_admin字段,根据判断is_admin字段的值,去对应管理员/用户表里查询对应的用户数据。 

表结构如下:

评论表(pinglun)
idcontentuser_idis_adminpid
1内容110null
2内容2111
3内容3102
4内容4113

 

 

 

 

 

用户表(user_wechat)
iduser_nickname
1张三

 

 

管理员表(sys_user)
idname
1李四

 

 

 

 

 

总的来说就这三张表,要用sql去实现上述需求,当时我也是没遇到过sql判断的情况,就去论坛里问了下大神,还是得到了解决。

sql如下:

SELECT pinglun.id,pinglun.content,IFNULL(user_wechat.user_nickname,sys_user.name) AS name
FROM pinglun
    LEFT JOIN user_wechat
        ON user_wechat.id = pinglun.user_id
           AND is_admin = 0
    LEFT JOIN sys_user
        ON sys_user.id = pinglun.user_id
           AND is_admin = 1;

 思路解析:

这里大神是用了mysql里的函数IFNULL,如果为空则返回第二个参数,即sys_user.name.,下面是左连接操作。

我们如果把IFNULL去掉,就会发现有些地方是null的,这是由于左连接的时候把is_admin=0等给加入了连接的on条件里。

这里用IFNULL就能实现这个功能了。

 

这里扩展一下,因为本来的实际需求是还要根据后面的pid去查询对应的包含自身的子节点。

这里贴一下当时看的帖子的链接:查询子节点

 

就不过多去说明了,里面其实写得挺细致的。我这里做一下针对自身的扩展。

即传入一个评论id,去查询对应评论id的包含自身的子节点,然后根据这个评论里的is_admin去查询对应不同表的用户/管理员信息。最后汇总。

 

SELECT w.id,w.content,IFNULL(user_wechat.user_nickname,sys_user.name) AS name,w.is_admin,w.pid
FROM (select id,user_id,pid,is_admin,content from (
              select t1.id,t1.is_admin,t1.user_id,t1.pid,t1.content,
              if(find_in_set(pid, @pids) >0, @pids := concat(@pids, ',', id), 0) as ischild
              from (
                   select id,is_admin,content,user_id,pid from pinglun t order by pid, id
                  ) t1,
                  (select @pids := 1) t2
             ) t3 where ischild !=0 or id = 1) w
    LEFT JOIN user_wechat
        ON user_wechat.id = w.user_id
           AND w.is_admin = 0
    LEFT JOIN sys_user
        ON sys_user.id = w.user_id
           AND w.is_admin = 1;

当时写下来就这么长,大概思路就是把查询子节点的数据,当成一张独立的表,然后根据这个表再去做IFNULL判断即可。

 

总结:

这个时候记录一下,其实这个功能,可以重新思考一下思路,我们现在的实现是纯sql语句来实现这个功能的,我也不太清楚这样做是不是好事。
不过实现起来确实过于复杂,虽然写起来很爽就是了。可是能遇见后期维护起来可能会很麻烦看到这么长这么复杂的sql语句。
所以这里其实可以这样来实现这个功能:
首先我们只需要按照第二步的sql去查询对应的包含自身的子节点。根据里面查找到的is_admin,在后台逻辑部分做一下处理,把is_admin和user_id传入工厂,我们由工厂去处理这一块问题,工厂判断如果is_admin是0,则访问某个接口,如果是1,则访问另外的接口即可。
或者在dao层接受第一次查询到的节点数据。mapper写的时候做一下if判断也可以实现。
不过这样的话会多次访问数据库,造成一些损耗。
所以总的来说,我也不知道哪个方法比较好,因为没有详细对比过,因为我这段sql语句,虽然只有一次访问,不过里面的耗时不一定就比多次访问简单sql快。
而且维护起来十分麻烦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值