Как объединить три таблицы с внешним соединением и декартовым произведением - PullRequest
2 голосов
/ 26 апреля 2011

У меня есть три таблицы в БД PostgreSQL: пользователи, действия, места.

Users:
- id
- name

Visits:
- id
- user_id
- location_id

Venues:
- id
- name

Я хочу получить все действия для конкретного пользователя, событие, если пользователь еще не посещал какое-либо место. Я пробовал это с некоторыми объединениями:

SELECT venues.id as venue, COUNT(activities.id) as visits
FROM users
RIGHT OUTER JOIN activities ON users.id=activities.user_id
RIGHT OUTER JOIN venues ON activities.venue_id=venues.id
WHERE users.id=1234
GROUP BY venues.id
ORDER BY venues.id

Я хочу, чтобы переменная посещения содержала 0, когда пользователь не посещал местоположение (= нет записей в действиях), и количество действий, если пользователь посетил местоположение.

Но я получаю только те места, которые посетил пользователь:

venue | visits
  1       3
  2       4
  3       22
  4       1

Я думал, что RIGHT OUTER JOIN вернет все записи с правой стороны, но это не так.

Ответы [ 2 ]

8 голосов
/ 26 апреля 2011

ВЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ означает, что вы хотите, чтобы все сущности из левой таблицы были выполнены независимо от того, выполнено ли условие (или предикат) СОЕДИНЕНИЯ.

Но это также один из тех редких случаев, когда декартово произведение (CROSS JOIN) действительно необходимо, так как вы хотите видеть каждое место для каждого пользователя. Попробуйте использовать CROSS JOIN , например:

SELECT v.id as venue, COUNT(a.id) as visits
FROM users AS u
CROSS JOIN venues as v --<-- CROSS JOIN for Cartesian product between users and venues
LEFT JOIN activities AS a ON u.id = a.user_id AND a.venue_id = v.id
WHERE u.id = 1234
GROUP BY v.id
ORDER BY v.id
2 голосов
/ 26 апреля 2011

Проверьте это:

http://db.apache.org/derby/docs/10.2/ref/rrefsqlj57522.html

Основные объяснения присоединения - они могут сбивать с толку. Я думаю, что вы либо хотите переключить столбцы в первом соединении, либо вместо этого используете левое внешнее объединение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...