Как объединить данные из 2 таблиц при определенных обстоятельствах? - PullRequest
0 голосов
/ 10 января 2010

У меня есть 2 таблицы. Одна таблица содержит сообщения, а другая содержит голоса за сообщения. Каждый участник может голосовать (+ или -) за каждый пост. (Пример структуры:)

  • Таблица сообщений: pid, owns, userp, text.
  • Таблица голосов: vid, userv, postid, голосования.

Также одна таблица, которая содержит информацию для пользователей.

То, что я хочу: Предположим, я вошел в систему. Я хочу показать все посты, и за те, за которые я уже проголосовал, не позволяйте мне голосовать снова. (и покажи мне, за что я голосовал + или -)

То, что я делал до сих пор, очень плохо, поскольку он будет выполнять много запросов:

SELECT `posts`.*, `users`.`username` 
FROM `posts`,`users` 
WHERE `posts`.belongs=$taken_from_url AND `users`.`usernumber`=`posts`.`userp` 
ORDER BY `posts`.`pid` DESC;

, а затем:

foreach ($query as $result) {if (logged_in) {select vote from votes....etc} }

Таким образом, это означает, что если я вошел в систему и показывает 30 сообщений, то он выполнит 30 запросов, чтобы проверить, голосовали ли я за каждое сообщение и за что я голосовал. У меня вопрос, могу ли я сделать это короче с JOIN (я думаю) и как? (Я уже что-то пробовал, но не получилось)

1 Ответ

0 голосов
/ 10 января 2010

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

Во-вторых, это должно сделать что-то вроде того, что вы хотите:

SELECT p.*, u.username,
  (SELECT SUM(vote) FROM votes WHERE postid = p.pid) total_votes,
  (SELECT vote FROM votes WHERE postid = p.pid AND userv = $logged_in_user_id) my_vote
FROM posts p
JOIN users u ON p.userp = u.usernumber
WHERE p.belongs = $taken_from_url
ORDER BY p.pid DESC

Примечание: Вы не говорите, каковы значения таблицы голосов. Я предполагаю, что это либо +1 (вверх) или -1 (вниз), так что вы можете легко найти общее количество голосов, сложив их. Если вы делаете это не так, я предлагаю вам сделать это, чтобы облегчить вашу жизнь.

Первый коррелированный подзапрос можно устранить, выполнив JOIN и GROUP BY, но я склонен находить приведенную выше форму гораздо более читабельной.

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

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