Rails 3 - сложный запрос активной записи / подзапросы - PullRequest
3 голосов
/ 01 августа 2011

У меня есть простая таблица истории с именем actions , которая выглядит следующим образом:

id | actionable_id | actionable_type | user_id
----------------------------------------------

actionable_types таблицы могут быть «comment», «voice» или «submission» сactionable_id, относящийся к первичному ключу каждой соответствующей таблицы.Кроме того, все комментарии и голоса принадлежат представлению.

Кроме того, у меня есть таблица дружеских отношений , которая выглядит следующим образом:

id | user_id | friend_id | user_id
----------------------------------

user_id таблицы относится к пользователю, которому принадлежит друг (а friend_id являетсядруг).

Если вы еще не догадались, каждый раз, когда пользователь комментирует, голосует или загружает новое представление, оно добавляется в таблицу истории как новое «действие».Получить все действия для друзей одного пользователя быстро и просто, и до сих пор работал замечательно.Тем не менее, это не моя проблема ...

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

Поэтому мне нужно выполнить следующие два запроса, предполагая, что current_user является в настоящее время вошедшим в систему пользователем.

Запрос 1 - все действия типа голосования, отвечающие следующим критериям:

  • они принадлежат не-друзьям текущего пользователя
  • онине принадлежат current_user
  • current_user имеет по крайней мере один голос, который принадлежит представлению (другими словами, если голос принадлежит этой коллекции, то существует хотя бы один голос вне коллекции, голос которой.user_id = current_user.user_id).

Запрос 2 - все действия типа комментарий, соответствующие следующим критериям:

  • они принадлежатNon-друзья пользователя current_user
  • они не принадлежат пользователю current_user
  • у current_user есть хотя бы один комментарий, относящийся к представлению (другими словами, если комментарий принадлежит этой коллекции, то существуетсуществует по крайней мере один комментарий за пределами коллекции, чей comment.user_id = current_user.user_id).

Поскольку оба запроса обращаются к одной и той же таблице действийДля меня было бы идеально иметь один запрос (хотя я считаю, что это крайне маловероятно, учитывая количество необходимых соединений).

Основное зависание на моем конце - это подзапросы, связанные с проверкой отсутствия дружеских отношений и последним условием каждого запроса (current_user имеет хотя бы один ...).Я избавлю вас от моего текущего кода базы запросов, поскольку он может даже не быть близко.

Спасибо за внимание и помощь.

1 Ответ

0 голосов
/ 04 августа 2013

Довольно сложный запрос, который вы хотели бы там. Вот мое предложение (при условии, что я правильно понял ваш запрос:

SELECT a.* FROM actions a
LEFT OUTER JOIN vote v
ON v.id=a.actionable_id AND a.actionable_type='vote'
LEFT OUTER JOIN comment c
ON c.id=a.actionable_id AND a.actionable_type='comment'
WHERE a.user_id<>current_user.id
AND NOT EXISTS (
  SELECT 1 FROM friendships f
  WHERE f.user_id=current_user.id
  AND f.friend_id=a.user_id
) AND EXISTS (
  SELECT 1 FROM submission s
  LEFT OUTER JOIN vote v1
  ON v1.submission_id=s.id
  LEFT OUTER JOIN comment c1
  ON c1.submission_id=s.id
  WHERE (v1.id IS NOT NULL
  AND v1.submission_id=v.submission_id
  AND v1.id<>v.id
  AND v1.user_id=current_user.id) OR
  (c1.id IS NOT NULL
  AND c1.submission_id=c.submission_id
  AND c1.id<>c.id
  AND c1.user_ud=current_user.id)
);

Поэтому я беру все действия и присоединяюсь к голосам и комментариям против действий. Затем я отфильтровываю все действия, идентичные user_id, которые есть у моего текущего пользователя. Убедитесь, что действие не от друга. И, наконец, я получаю материалы и присоединяюсь к голосам current_users и комментариям против них, и когда для представления существует голосование или комментарий, то есть то же самое, что и для выбранного действия, я обнаружил действие для не друга пользователя Вы ищете.

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