Соотношение многих ко многим - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть следующие объекты:

@Entity
class User {
    @ManyToMany(type => Group)
    @JoinTable()
    groups: Group[];
}

@Entity
class MediaObject {
    @ManyToMany(type => Group)
    @JoinTable()
    groups: Group[];
}

@Entity
class Group {
    // [...]
}

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

Пример:

User 1          MediaObject 1
-----------------------------
Group 1    |--- Group 2 
Group 2 ---|    Group 3

User 1 has at least one same group as MediaObject

Как мне создать SQL-запрос where для этого?Я использую typeorm для построения своих запросов, но каждый SQL-запрос поможет.Также я хочу понять как.Typeorm присоединяется к таким таблицам

LEFT JOIN "group" "groups" ON "groups"."id" = "media_groups"."groupId" 

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Если между одним и тем же MediaObject и одним и тем же User может быть несколько перекрывающихся групп, полусоединение EXISTS может быть быстрее, чем при использовании IN:

SELECT m.*
FROM   "MediaObject" m
WHERE  EXISTS (
   SELECT -- select list can be empty here
   FROM   user_groups_group         gu
   JOIN   media_object_groups_group gm USING ("groupId")
   WHERE  gu."userId" = 1
   AND    gm."mediaObjectId" = m.id
   );

Иначе, Запрос Радима должен хорошо работать после добавления нескольких двойных кавычек.

Это предполагает, что ссылочная целостность обеспечивается ограничениями внешнего ключа, поэтому можно безопасно полагаться на user_groups_group."userId" без проверки соответствующего пользователя.даже существует.

Неразумно использовать в качестве идентификаторов зарезервированные слова , например "user" или строки "group" или CaMeL-case.Либо требует двойных кавычек.ОРМ регулярно плохо работают в этом отношении.См .:

0 голосов
/ 10 декабря 2018

Используя простой JOIN, вы можете получить MediaObject Id, которые делят с пользователем хотя бы одну группу.Чем использовать IN для получения MediaObject

select *
from MediaObject mo
where mo.id in
(
    select moJoin.mediaObjectId
    from media_object_groups_group moJoin
    join user_groups_group uJoin on moJoin.groupId = uJoin.groupId
    where uJoin.userId = 1
)
...