Как сделать запрос на включение и исключение в SQL / Active Record? - PullRequest
0 голосов
/ 19 сентября 2018

Проблема

У меня есть три модели, значительно упрощенные для целей этого вопроса:

User:
- id

Event:
- id
- user_id (FK)

Stream:
- id
- event_id (FK)
- user_id (FK)

Я использую PostgresQL

Допустим, у меня есть два пользователя с идентификаторами: 1, 2.

Я хочу получить все События, у которых есть хотя бы один Поток, по Пользователю 1. Я также хочу исключить любые События, у которых есть хотя бы один Потокпо пользователю 2.

Набор данных

Stream: ID: 1, User: 1, Event: 1
Stream: ID: 2, User: 1, Event: 1
Stream: ID: 3, User: 1, Event: 2
Stream: ID: 4, User: 2, Event: 2
Stream: ID: 5, User: 2, Event: 3
Stream: ID: 6, User: 2, Event: 3

Для целей данного примера предположим, что это все потоки в системе.

Текущий запрос активной записи

# Keep in mind this is on the User model.  So self=User 1

Event.joins(:streams)
    .merge( Stream.where(user: self).where.not(user: User.find(2)) )
    .....

Результирующий запрос:

SELECT events.*
FROM events
INNER JOIN streams ON streams.event_id = events.id
WHERE streams.user_id = 1 AND streams.user_id != 2

Текущий результат

Ожидаемый:

Event 1

Факт:

Event 1
Event 2

В настоящее время это соответственно возвращает только события, имеющие по крайней мере один поток пользователя 1, однако это не исключает те события, которые также имеют по крайней мере один поток пользователем 2.

Как правильно выполнить это в SQL и ненужный бонус в Active Record?

1 Ответ

0 голосов
/ 19 сентября 2018

Попробуйте это

SELECT events.*
FROM events ev
INNER JOIN streams st
ON st.event_id = ev.id
and st.user_id = 1 
left join streams st1
ON st1.event_id = ev.id
and st1.user_id = 2
where st1.event_id is null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...