Friendfeed показывает одни и те же отношения дважды - PullRequest
0 голосов
/ 05 августа 2011

Я создавал систему кормления аля фейсбук только для развлечения и обучения, но у меня возникла интересная проблема.Представьте себе такой сценарий:

Я дружу с nr1, nr2 и nr3.В моей базе данных это также пользователь nr4 в базе данных, с которым я не дружу.Итак, скажем, nr1, подружиться с nr4, в этом случае я хочу, чтобы мой фид обновлялся с помощью nr1, и с nr4.Это базовый, не очень сложный для выполнения (по крайней мере, чтобы заставить его работать, я не знаю, о производительности: P).Тогда nr1 подружиться с nr2, но это эквивалентно nr2 подружиться с nr1, и это моя проблема.

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

Таблица дружбы:

  • user_id
  • friend_id
  • в ожидании
  • lastchange

Таблица пользователей:

  • user_id
  • user_name

Я получил следующий код:

SELECT
    u1.user_id AS friend_id,
    u1.user_name SA friend_name,
    u2.user_id AS friends_friend_id,
    u2.user_name AS friends_friend_name
FROM users AS u1
JOIN friendship AS f1
    ON u1.user_id = f1.friend_id
    && f1.user_id = {$user_id}
    && f1.friend_pending = 0
JOIN friendship AS f2
    ON u1.user_id = f2.user_id
    && f2.friend_pending = 0
JOIN users AS u2
    ON f2.friend_id = u2.user_id
WHERE TIMESTAMPDIFF(SECOND, f2.lastchange, '{$last_login}' ) < 0;

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

  • в первый раз nr1 будет другом, а nr 2 - другом и

  • во второй раз nr2 будет другом, а nr1быть друзьями друг

Я не хочу этого, я хочу один ряд на отношения.

У вас, ребята, есть идеи, как решить эту проблему?Любое решение, которое я нашел, закончилось, и ничего не отображалось: (

Спасибо!

1-е редактирование: Я только что столкнулся с другой проблемой, которая также связана с этимпроблема. В phpMyAdmin выше генерируется правильная таблица с четырьмя столбцами. Но в php (или, скорее, в функции запроса codeigniter) он показывает только два столбца, но добавляет больше строк ... в итоге я понятия не имею, кто подружится с кем ..

2-е редактирование еще раз: Окей, я только что решил проблему, которую я представил в первом редактировании, я просто переименовал столбцы с AS. Тем не менее основная проблема у вас.

3-е редактирование: Стиви Дж запрашивал некоторые примеры данных, это результат запроса:

friend_id  |  friend_name  |   friends_friend_id  |  friends_friend_name
    1             nr1                  4                   nr4
    1             nr1                  2                   nr2     
    2             nr1                  1                   nr2

Это то, что я получу, если вы последуете моей маленькой истории. id = 1это не «я», это другой пользователь

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

  • friend_id
  • friend_name
  • friends_friend_id
  • friends_friend_name

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

friend_id  |  friend_name  |   friends_friend_id  |  friends_friend_name
    1             nr1                  2                   nr2     
    2             nr1                  1                   nr2

Надеюсь, я прояснил ситуацию!Спасибо

Ответы [ 4 ]

0 голосов
/ 12 июля 2013

Так что мне кажется, что ваши требования неполные, в том, что в фиде друзей, если nr2 и nr1 дружат друг с другом, вы хотите:

  1. Посмотрите что-то, что говорит:друзья nr2 и nr1 подружились друг с другом! "
  2. Посмотрите что-нибудь, что говорит" Ваш друг nr2 подружился с nr1! "в зависимости от того, кто первым обратился за дружбой.

Сценарий # 1

Вам нужно еще раз присоединиться, чтобы проверить, есть ли друзья ваших друзей в ваших друзьях иесли это так, возвращая логический столбец с именем Кроме того, MyMyFriend.Затем, если «Кроме того, значение« 1 »» равно 1, верните «Ваши общие друзья подружились друг с другом», в противном случае верните обычное «Ваш друг подружился с кем-то новым».

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

Сценарий # 2

Добавить столбец в дружба таблица * primary_mover * и установите это значение в * user_id *, который инициировал дружбу.При поиске в друзьях выберите фильтр *, где primary_mover = user_id *, чтобы получить только 1 из 2-сторонних отношений.

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

SELECT
    u1.user_id AS friend_id,
    u1.user_name SA friend_name,
    u2.user_id AS friends_friend_id,
    u2.user_name AS friends_friend_name
FROM users AS u1
JOIN friendship AS f1
    ON u1.user_id = f1.friend_id
    && f1.user_id = {$user_id}
    && f1.friend_pending = 0
JOIN friendship AS f2
    ON u1.user_id = f2.user_id
    && f2.friend_pending = 0
    && f2.friend_id > f2.user_id -- pulls nr1 befriending nr2, not nr2 befriending nr1
JOIN users AS u2
    ON f2.friend_id = u2.user_id
WHERE TIMESTAMPDIFF(SECOND, f2.lastchange, '{$last_login}' ) < 0;
0 голосов
/ 05 августа 2011

Это сложно сделать в вашей голове, но попробуйте это:

SELECT  --Select your user details, and your direct friends details
    u1.user_id UserId,
    u1.user_name UserName,
    u2.user_id FriendsUserId,
    u2.user_name FriendsUserName
FROM users AS u1
JOIN friendship AS f1
    ON u1.user_id = {$user_id}
    && f1.friend_pending = 0
JOIN users AS u2
    ON f1.friend_id = u2.user_id
JOIN friendship AS f2
    ON f1.friend_id = f2.userid
    && f2.friend_pending = 0
WHERE TIMESTAMPDIFF(SECOND, f2.lastchange, '{$last_login}' ) < 0;
UNION 
SELECT  --Select your user details, and your friends friends details
    u3.user_id UserId,
    u3.user_name UserName,
    u4.user_id FriendsUserId,
    u4.user_name FriendsUserName
FROM users AS u3
JOIN friendship AS f3
    ON u3.user_id = {$user_id}
    && f3.friend_pending = 0
JOIN friendship AS f4
    ON f3.friend_id = f4.user_id
    && f4.friend_pending = 0 
JOIN users AS u4
    ON f3.friend_id = u4.user_id
WHERE TIMESTAMPDIFF(SECOND, f4.lastchange, '{$last_login}' ) < 0;

Предполагая, что результаты такие, как я думаю, UNION должен отфильтровать дубликаты, поскольку u1.user_id всегда должен быть вашим user_id.

0 голосов
/ 05 августа 2011

Попробуйте

SELECT     
    u1.user_id AS friend_id,     
    u1.user_name SA friend_name,     
    u2.user_id AS friends_friend_id,     
    u2.user_name AS friends_friend_name 
FROM users AS u1 
JOIN friendship AS f1     
    ON u1.user_id = f1.friend_id     
     && f1.user_id = {$user_id}     
     && f1.friend_pending = 0 
JOIN friendship AS f2     
    ON u1.user_id = f2.user_id     
     && f1.user_id <> f2.friend_id 
     && f2.friend_pending = 0 
JOIN users AS u2     
     ON f2.friend_id = u2.user_id 
WHERE TIMESTAMPDIFF(SECOND, f2.lastchange, '{$last_login}' ) < 0; 
0 голосов
/ 05 августа 2011

Вы пытались использовать

SELECT DISTINCT
...