Несколько таблиц JOIN возвращает двойные результаты, стена активности в стиле Facebook - PullRequest
4 голосов
/ 10 апреля 2011

Быстрое подведение итогов: у меня есть социальный веб-сайт, на котором пользователи могут следить / публиковать / голосовать и т. Д. Я добавляю новую фейсбук-функцию стены активности в профили каждого пользователя.

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

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

Я работаю с 3 таблицами здесь (я разместил только те столбцы, которые я использую):

Table structure for table votes_posts
Field   Type    Null    Default
indexer int(11) No  
post_id int(11) No  
vote    int(11) No  
user_name   varchar(250)    No  
date    varchar(255)    No  

Table structure for table posts
Field   Type    Null    Default
id  int(11) No  
name    varchar(30) No  
content text    No  
datetimerss varchar(255)    No  
category    int(11) No  

Table structure for table comments
Field   Type    Null    Default
id  int(12) No  
post_id int(12) No  
name    varchar(30) No  
content text    No  
type    varchar(30) No  
datetimerss varchar(255)    No

$ users - это всего лишь $ _GET ['user'] TimeAgo (), просто отображает очень популярную дату «опубликовано хх назад».

<ul class="streamActivity">
<?php
$checkActivity = "SELECT votes_posts.post_id, votes_posts.user_name, votes_posts.vote, votes_posts.date, 
                        posts.id, posts.content, posts.name, posts.datetimerss, categories.category, 
                        comments.post_id AS comm_postid, comments.content AS comm_content, comments.name AS comm_name, comments.datetimerss AS comm_date, comments.type 
                        FROM `votes_posts` 
                        LEFT OUTER JOIN `posts` ON votes_posts.post_id = posts.id 
                        LEFT OUTER JOIN `comments` ON posts.id = comments.post_id 
                        LEFT OUTER JOIN `categories` ON posts.category = categories.cat_id  
                        WHERE (votes_posts.post_id = posts.id AND user_name = '$user')
                        OR (comments.post_id = posts.id AND comments.name = '$user')
                        OR (posts.name = '$user') ORDER BY votes_posts.date, posts.datetimerss, comments.datetimerss ASC";
$checkActivityResult = mysql_query($checkActivity);

if (mysql_num_rows($checkActivityResult) > 0) {
    while ($sessionAct = mysql_fetch_array($checkActivityResult)) {
        $category = strtolower($sessionAct['category']);
        $dateVote = timeAgo($sessionAct['date']);
        $datePost = timeAgo($sessionAct['datetimerss']);
        $dateComm = timeAgo($sessionAct['comm_date']);

        $namePost = $sessionAct['name'];
        $nameComm = $sessionAct['comm_name'];
        $nameVote = $sessionAct['user_name'];

        $idVote = $sessionAct['post_id'];
        $idPost = $sessionAct['id'];
        $idComm = $sessionAct['comm_postid'];

        $contentPost = $sessionAct['content'];
        $contentComm = $sessionAct['comm_content'];
        $typeComm = $sessionAct['type'];

        if ($namePost == $user) {
            $classList = 'storyPost';
            $classIcon = 'iconMuttr';

            $name = $namePost;
            $content = $contentPost .' ... read more';
            $datetime = $datePost;
        }

        elseif ($nameComm == $user && $typeComm == "Comment") {
            $classList = 'actionPost';
            $classIcon = 'iconComment';

            $name = $nameComm;
            $content = 'Commented "'. $contentComm .'"';
            $datetime = $dateComm;
        } elseif ($nameComm == $user && $typeComm == "Advice") {
            $classList = 'actionPost';
            $classIcon = 'iconAdvice';

            $name = $nameComm;
            $content = 'gave Advice "'. $contentComm .'"';
            $datetime = $dateComm;
        }

        elseif ($nameVote == $user) {
            if ($sessionAct['vote'] == "1") {
                $classList = 'actionPost';
                $classIcon = 'iconLaughed';

                $name = $nameVote;
                $content = 'Laughed at "'. $contentPost .'"';
                $datetime = $dateVote;
            } elseif ($sessionAct['vote'] == "2") {
                $classList = 'actionPost';
                $classIcon = 'iconLoved';

                $name = $nameVote;
                $content = 'Showed Love on "'. $contentPost .'"';
                $datetime = $dateVote;
            } elseif ($sessionAct['vote'] == "3") {
                $classList = 'actionPost';
                $classIcon = 'iconIdiot';

                $name = $nameVote;
                $content = 'called '. $namePost .' an Idiot for "'. $contentPost .'"';
                $datetime = $dateVote;
            }
        }
?>
    <li class="row-activity <?php echo $classList; ?>">
        <a href="" class="avatar"><img src="/images/avatars/default_male.jpg" /></a>
        <div class="info">
            <div class="userName">
                <a href=""><?php echo $name; ?></a>
            </div>
            <span class="msgBody"><?php echo $content; ?></span>
            <div class="imgTimeStream">
                <span class="img <?php echo $classIcon; ?>"></span>
                <span class="source"><?php echo $datetime; ?></span>
            </div>
        </div>
    </li>
<?php
    }
} else {
    echo '<p>This user has no recent activity.</p>';
}
?>
</ul>

Я ни в коем случае не опытный программист ... все, что я знаю, я многому научил за последний год илидва, так что я могу только представить, насколько уродливым это действительно LOL.Хотя я учусь каждый день и надеюсь продолжить:)

Кроме того, в каждом типе деятельности будут некоторые классы CSS для некоторых вещей.Пример: если результирующая строка представляет собой сообщение, то класс css элемента списка будет «post», если результирующая строка представляет собой голосование, то класс css элемента списка будет «голосовать» и т. Д.

Буду признателен за любую помощь!

ОБНОВЛЕНИЕ: Ну, несколько запросов, похоже, работали нормально ... больше никаких дубликатов.У меня даже он отображает только последние пару месяцев активности (пока, во всяком случае).Теперь мне нужно выяснить, как смешать результаты, чтобы самые последние результаты (будь то голосование, публикация и т. Д.) Были на самом верху.

PS Я, наверное, должен упомянуть, что МНОГО данных будетпроходя через это (подумайте о стене в фейсбуке + твиттер лол)

1 Ответ

3 голосов
/ 10 апреля 2011

Вы должны превратить ваш запрос в объединение из 3 операторов (голосов, сообщений, комментариев), которые возвращают один и тот же набор столбцов.Что происходит в вашем запросе, так это то, что несколько голосов, сообщений или комментариев умножают строки, сгенерированные запросом.

Кроме того, вам следует перейти на использование параметризованного SQL, если это возможно, чтобы устранить потенциальные уязвимости внедрения SQL.

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