简体   繁体   English

从group_concat使用

[英]Using in from a group_concat

So I have two tables, one holding all users, and the other holding users with their corresponding groups. 因此,我有两个表,一个表容纳所有用户,另一个表容纳具有相应组的用户。 What I'm trying to do is to get all the user ids in the second table to get all the information I need from the first table. 我想要做的是获取第二个表中的所有用户ID,以从第一个表中获取我需要的所有信息。 My explanation is a bit messy, but I think the code below should be clear enough 我的解释有点混乱,但是我认为下面的代码应该足够清楚

SELECT
    *
FROM
    USER
WHERE
    id IN (
        SELECT
            group_concat(userid)
        FROM
            user_membership
        WHERE
            groupid = 45
    );

However, what returns is the empty set. 但是,返回的是空集。 When I replace the 'in' with an '=' it returns a single entry (as expected). 当我将'in'替换为'='时,它将返回单个条目(如预期)。 What's wrong with my syntax? 我的语法有什么问题? Thanks. 谢谢。

You don't need group_concat() here as it concatenates every userid into a string column and you need to compare each user.id with a single user_membership.userid value, not an entire set. 您无需在这里使用group_concat() ,因为它将每个userid连接到一个字符串列中,并且需要将每个 user.id与单个user_membership.userid值(而不是整个集合)进行比较。 It's an overkill to perform that operation. 执行该操作实在是太过分了。

Simple select would suffice. 简单选择就足够了。 However, it will probably be more efficient to rewrite your query using EXISTS : 但是,使用EXISTS重写查询可能会更有效:

select *
from user u
where exists (
  select 1
  from user_membership um
  where u.id = um.userid
    and groupid = 45
  )

If you really insist on the IN clause then correct query would look: 如果您真的坚持使用IN子句,那么正确的查询将如下所示:

select *
from user
where id in (
  select userid
  from user_membership
  where groupid = 45
  )

You can use FIND_IN_SET 您可以使用FIND_IN_SET

SELECT
 *
FROM USER
WHERE
FIND_IN_SET(id ,( SELECT group_concat(userid) FROM user_membership WHERE groupid = 45 ))

You can use INNER JOIN 您可以使用INNER JOIN

SELECT
    U.*
FROM USER U 
INNER JOIN user_membership UM ON UM.userid = U.id 
WHERE UM.groupid = 45

Or you can use EXISTS like Kamil G mentioned in his answer. 或者,您也可以使用答案中提到的像Kamil G这样的EXISTS

id is a number, group_concat returns a string, containing all the ids separated by comma. id是一个数字, group_concat返回一个字符串,其中包含所有用逗号分隔的id。 I do not know the cause of the behavior you experienced, but I believe you could resolve the problem like this: 我不知道您遇到这种行为的原因,但我相信您可以解决以下问题:

SELECT
    *
FROM
    USER
WHERE
    (
        SELECT
            CONCAT(',', CONCAT(group_concat(userid), ','))
        FROM
            user_membership
        WHERE
            groupid = 45
    ) LIKE CONCAT(',', CONCAT(id, ','));

Explanation: we write comma at the start and end of the inner result to allow LIKE to have a general operator. 说明:我们在内部结果的开头和结尾处都使用逗号,以使LIKE具有通用运算符。 But your query can be optimized if you use EXISTS : 但是,如果使用EXISTS则可以优化查询:

SELECT
    *
FROM
    USER
WHERE
    EXISTS (
        SELECT
            1
        FROM
            user_membership
        WHERE
            user_membership.groupid = 45 and user_membership.userid = USER.id
    );

Looks much more like a job for a join 看起来更像是一份工作

SELECT
    *
FROM
    USER u inner join 
     user_membership m on m.userid = u.id
WHERE
         m.groupid = 45
   ;

That should run much faster as the query can more easily use the index 这应该运行得更快,因为查询可以更轻松地使用索引

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM