MySQL Many-Many Query Problem

Вот моя проблема. У меня есть many-many таблица, названная 'user_has_personalities'. В моем приложении у пользователей могут быть многие личности, и личность может принадлежать многим пользователям.

Таблица имеет два целочисленных столбца, user_id и personality_id.

То, что я должен сделать, получают всех пользователей, которые имеют по крайней мере все личности (ряд personality_ids переменного размера), который я предоставляю к запросу.

Для примера я хотел бы получить всех пользователей, которые имеют личности с идентификаторами 4, 5, 7, но могут также иметь некоторые другие личности. Но мне нужен запрос для работы на переменное количество требуемых идентификаторов личности, как 4, 5, 7, 9, 10 для примера.

Какие-либо идеи?

11
задан Martin Vrkljan 9 February 2010 в 16:24
поделиться

3 ответа

Нет такого понятия, как лучшие инструменты, которые можно купить за деньги.

Нет, это эвфемизм для отношения, которое отвергает ложную экономику мириться с низшими инструментами ради подсчета бобов.

-121--1663359-

Во-первых, у вас не должно быть полей artist_id и художника. Они строятся из модели. Если вам нужно имя исполнителя, добавьте artist_name поле, то есть CharField .

Кроме того, вы пытаетесь извлечь что-то из cleaned_data внутреннего чистого значения. Могут отсутствовать необходимые данные - следует использовать значения из self.data, где - данные непосредственно из POST.

-121--2053916-

Этот запрос выполняет задачу:

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>

Необходимо указать разделенный запятыми список идентификаторов личности для < список идентификаторов личности > , а также указать количество предметов в списке. Придерживаясь своего примера, вы получите:

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

это гарантирует, что вы получите только пользователей, которые имеют все эти личности.

6
ответ дан 3 December 2019 в 09:41
поделиться
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 , identity_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
ответ дан 3 December 2019 в 09:41
поделиться
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
ответ дан 3 December 2019 в 09:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: