SQL JOINS получает и отображает дважды - PullRequest
0 голосов
/ 02 сентября 2011

Я объединяю 2 таблицы и пытаюсь отобразить результаты. Единственная проблема - каждый результат дублируется. У меня есть 2 таблицы, сообщения и следите. Сообщения - это то, что вводит определенный пользователь, и я хочу, чтобы оно отображалось только тем, кто подписан на этого определенного пользователя.

Messages | Follow
-id        -id
-message   -mem1 (logged in user)
-userid    -mem2 (followed user)
-created

$display ="";
$sql = mysql_query("
SELECT * FROM messages AS me 
JOIN follow AS fl 
ON me.userid = fl.mem2 
WHERE fl.mem1 = $id (logged in user)
ORDER BY me.created 
DESC LIMIT 10
") or die(mysql_error());
while($row=mysql_fetch_array($query)){
$msgid = $row["id"];
$message = $row["message"];
$userid = $row["userid"];
$created = $row["created"];

$display .="<?php echo $userid; ?> : <?php echo $message; ?><br />
<?php echo $created; ?>";
}

В базе данных нет дубликатов, только при получении. Спасибо за вклад!

Отредактировано: Показать код

Ответы [ 3 ]

1 голос
/ 02 сентября 2011

На самом деле есть только несколько вещей, которые могут вызвать дублирование записей - попробуйте разбить запрос на базовые компоненты, чтобы увидеть, существует ли более одной записи:

SELECT * FROM follow WHERE mem1 = [id];
SELECT * FROM messages WHERE userid = [mem2 from previous result];

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

Что касается самого запроса, у меня есть несколько рекомендаций:

  • Разместитьсначала таблица с фильтром - чем раньше вы сможете сузить результаты, тем лучше.
  • Укажите список полей вместо '*' - это будет чуть-чуть эффективнее и проясните, что вам нужно,Кроме того, это даст «DISTINCT» шанс на боевые действия ...

Вот пример:

SELECT DISTINCT me.id, me.message, me.userid, me.created
    FROM follow AS fl 
    INNER JOIN messages AS me ON me.userid = fl.mem2 
    WHERE fl.mem1 = :logged_in_user
    ORDER BY me.created 
    DESC LIMIT 10
1 голос
/ 02 сентября 2011

Вы получаете "двойные" результаты, скорее всего потому, что запрос приводит к чему-то другому, чем вы ожидаете.

Если я правильно понимаю вашу структуру таблиц; у вас есть отношение один-ко-многим из сообщений фолловерам.

Однако в своем запросе вы выбираете комбинации сообщений и подписчиков. Каждая строка будет состоять из уникальной комбинации сообщения <> follower.

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

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

Если вы просто пытаетесь получить количество подписчиков; вы можете использовать группирование по UID вашей таблицы сообщений и добавить счетчик по UID или идентификатору пользователя в таблице последователей. (Не делайте этого с group-by, выборка * из не должна использоваться; но отдельные столбцы могут.)

1 голос
/ 02 сентября 2011

Если вы уверены, что дубликатов нет, и проблема в запросе (вы можете проверить это, выполнив его из интерфейса вашей базы данных), вы можете попробовать две вещи:

  • Используйте таблицу follow в качестве ведущей:

    SELECT messages.*
    FROM follow
    JOIN messages ON follow.mem2=messages.userid
    WHERE follow.mem1=$id
    ORDER BY messages.created DESC
    LIMIT 0,10;
    
  • Использовать подзапрос:

    SELECT *
    FROM messages
    WHERE userid IN(
        SELECT DISCTINCT(mem2)
        FROM follow
        WHERE mem1=$id
        )
    ORDER BY created DESC
    LIMIT 0,10;
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...