查询需求:用户可以邀请其他人,而用户又可以被其他人邀请,查询出所有跟邀请人有关的邀请人id->结果作为条件
查询过程:根据inviter_id(邀请人)查询visitor_id(被邀请人)中有inviter_id的所有inviter_id 再加上自身的inviter_id
-
首先想到了用一个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丢掉了。
具体原因不知道,猜测是无论子查询有多少结果,生效的只是第一个逗号前的值 -
查找其他替代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拼接出来的,直接一个括号中间放逗号肯定会有问题,继续优化
- 使用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有。最后什么都查不出来
- 最后完善结果,使用判断函数IFNULL或者IF都可以
此时已经确定了,只要子查询结果正确,结果就正确
SELECT CONCAT(
IFNULL(GROUP_CONCAT(inviter_id),'-1'),',', 1337341587499253760)
FROM rv_user_invite WHERE visitor_id = 1337341587499253760)