问题 MySQL多对多查询问题


这是我的问题。我有一个名为'user_has_personalities'的多对多表。在我的应用程序中,用户可以拥有许多个性,个性可以属于许多用户。

该表有两个整数列,user_id和personality_id。

我需要做的是让所有用户至少拥有我提供给查询的所有个性(一组可变大小的个性化用户)。

举个例子,我想让所有具有ids 4,5,7个性的用户,但也可以拥有其他一些个性。但是我需要查询来处理可变数量的通缉个性ID,例如4,5,7,9,10。

有任何想法吗?


5696
2018-02-09 16:24


起源



答案:


此查询完成工作:

select  user_id
from    user_has_personalities
where   personality_id in (<list-of-personality-ids>)
group by user_id
having count(*) = <numer-of-items-in-IN-list>

您需要提供以逗号分隔的个性ID列表 <list-of-personality-ids> 而且你还需要提供精英中的物品数量。坚持你的榜样,你会得到:

select  user_id
from    user_has_personalities
where   personality_id in (4,5,7)
group by user_id
having count(*) = 3

这可确保您只获得具有所有这些个性的用户。


6
2018-02-09 16:29



这只是告诉他们是否有一个personality_id。问题明确地说明了所有的ID。 - Evan Carroll
@Evan:此查询告诉用户是否具有所有ID。 - Quassnoi
我明白你在做什么。尼斯。 - Evan Carroll
+ 1,这是怎么做的。 - David Oneill
谢谢!它很棒。 - Martin Vrkljan


答案:


此查询完成工作:

select  user_id
from    user_has_personalities
where   personality_id in (<list-of-personality-ids>)
group by user_id
having count(*) = <numer-of-items-in-IN-list>

您需要提供以逗号分隔的个性ID列表 <list-of-personality-ids> 而且你还需要提供精英中的物品数量。坚持你的榜样,你会得到:

select  user_id
from    user_has_personalities
where   personality_id in (4,5,7)
group by user_id
having count(*) = 3

这可确保您只获得具有所有这些个性的用户。


6
2018-02-09 16:29



这只是告诉他们是否有一个personality_id。问题明确地说明了所有的ID。 - Evan Carroll
@Evan:此查询告诉用户是否具有所有ID。 - Quassnoi
我明白你在做什么。尼斯。 - Evan Carroll
+ 1,这是怎么做的。 - David Oneill
谢谢!它很棒。 - Martin Vrkljan


SELECT  *
FROM    (
        SELECT  DISTINCT user_id
        FROM    user_has_personalities
        ) uhpo
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    user_has_personalities uhpi
        WHERE   uhpi.user_id  = uhpo.user_id
                AND personality_id IN (4, 5, 6, 9, 10)
        LIMIT 1 OFFSET 4
        )

偏移值应该是 1 少于该项目的数量 IN 名单。

如果您将个性列表放在专用表中,请使用以下命令:

SELECT  *
FROM    (
        SELECT  DISTINCT user_id
        FROM    user_has_personalities
        ) uhpo
WHERE   (
        SELECT  COUNT(*)
        FROM    perslist p
        JOIN    user_has_personalities uhpi
        ON      uhpi.user_id = uhpo.user_id
                AND uhpi.personality_id = p.id
        ) =
        (
        SELECT  COUNT(*)
        FROM    perslist
        )

为了正常(和快速)工作,你需要有一个 UNIQUE 索引 user_has_personalities (user_id, personality_id) (按此顺序)。

如果你有 users 表和几乎所有用户都有记录 user_has_personalities,然后用它代替 DISTINCT 嵌套查询:

SELECT  user_id
FROM    users uhpo
WHERE   (
        SELECT  COUNT(*)
        FROM    perslist p
        JOIN    user_has_personalities uhpi
        ON      uhpi.user_id = uhpo.user_id
                AND uhpi.personality_id = p.id
        ) =
        (
        SELECT  COUNT(*)
        FROM    perslist
        )

4
2018-02-09 16:30



一般掌握和向导的+1 :) Quassnoi,我喜欢你的博客,我和你联系。如果您打开评论,我希望您的博客更多,但显然您有权将其保留原样。无论如何,欢呼并继续:) - Roland Bouman
@Roland:类别中的每篇文章 Miscellaneous 已启用评论。 - Quassnoi
好的,公平的:)谢谢。 - Roland Bouman


SELECT a.user_id
FROM user_has_personalities a
JOIN user_has_personalities b ON a.user_id = b.user_id AND b.personality_id = 5
JOIN user_has_personalities c ON a.user_id = c.user_id AND b.personality_id = 7
WHERE a.personality_id = 4

以编程方式生成此列表很容易,但它并不像提供集合那么容易。另一方面,它是有效的。


1
2018-02-09 16:49