SQL IN 里面放GROUP_CONCAT子查询

查询需求:用户可以邀请其他人,而用户又可以被其他人邀请,查询出所有跟邀请人有关的邀请人id->结果作为条件
查询过程:根据inviter_id(邀请人)查询visitor_id(被邀请人)中有inviter_id的所有inviter_id 再加上自身的inviter_id

image.png

  1. 首先想到了用一个in语句,in里面放一个子查询,子查询后面拼上自己的id

     WHERE ui.user_id IN (
       (SELECT GROUP_CONCAT(inviter_id) 
       FROM rv_user_invite WHERE visitor_id = 1340843848854667264),1340843848854667264
     )
    

    一开始也没有报错,所以看来是没有问题的,后来经过测试发现查询的结果跟数据库里的结果不匹配,最后的结果少了一个子查询的第二个id
    比如,in里面的结果是1339127322933985280,1337341587499253760, 1340843848854667264。最后把1337341587499253760丢掉了。
    具体原因不知道,猜测是无论子查询有多少结果,生效的只是第一个逗号前的值

  2. 查找其他替代in的方法:FIND_IN_SET

    FIND_IN_SET(
    ui.user_id,(
    (SELECT GROUP_CONCAT(inviter_id)
     FROM rv_user_invite WHERE visitor_id = 1340843848854667264),
    1340843848854667264)) 
    

此时会报错1241 - Operand should contain 1 column(s), Time: 0.012000s
FIND_IN_SET的第二个参数应该放置由concat拼接出来的,直接一个括号中间放逗号肯定会有问题,继续优化

  1. 使用sql里的拼接函数CONCAT
FIND_IN_SET(
ui.user_id,(
SELECT CONCAT(GROUP_CONCAT(inviter_id) ,',', 1340843848854667264)
FROM rv_user_invite 
WHERE visitor_id = 1340843848854667264))

这样就可以了,但是此时又忽略了一个重要条件
CONCAT函数拼接过程中只要有一个为null,其结果就为null
测试中可以把参数换成1337341587499253760,这个id在visitor_id列中没有,在inviter_id有。最后什么都查不出来

  1. 最后完善结果,使用判断函数IFNULL或者IF都可以
    此时已经确定了,只要子查询结果正确,结果就正确
SELECT CONCAT(
IFNULL(GROUP_CONCAT(inviter_id),'-1'),',', 1337341587499253760)
 FROM rv_user_invite WHERE visitor_id = 1337341587499253760)

你可能感兴趣的:(SQL IN 里面放GROUP_CONCAT子查询)