Только друзья, которые не являются общими для обоих пользователей

Вот мои таблицы:

1): таблица друзей:

 id_invitation     
 id_exp            
 id_des       
 date_invitation
 active            

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

 id        
 prenom      
 nom          
 email        
 password    

У меня есть два запроса:

1: Первый возвращает мне список друзей.

SELECT *
  FROM users U
  JOIN friends F
    ON ( U.id = F.id_exp AND F.id_des = :id )
    OR ( U.id = F.id_des AND F.id_exp = :id )
 WHERE U.id <> :id
   AND F.active = 1

2: вторая возвращает только общих друзей между двумя пользователями.

SELECT u.id
     , u.nom
     , u.prenom
  FROM users u
  JOIN 
     ( SELECT id_exp
            , id_des
         FROM friends
        WHERE id_exp IN(:id_exp, :id_des)
          AND active = 1
        UNION
       SELECT id_des
            , id_exp
         FROM friends
        WHERE id_des IN(:id_exp, :id_des)
          AND active = 1
     ) tmp  
    ON tmp.id_des = u.id 
 GROUP 
    BY u.id 
HAVING COUNT(*) = 2

Небольшая коррекция:

1 - общий друг между 2 и 3, так как он является другом с 2 и 3 (если вы хотите собрать общего друга в 2 и 3, у вас будет 1). 4 дружит с 2, но не с 3. А 3 также дружит с 5 и 6, я хочу найти в списке друзей 2, восстановить друзей из 2, но которые не дружат с 3 (в данном случае 4). Я хочу вернуть только 4, а не 4,5,6

Больше информации: я хочу, чтобы, когда 3 посещает список необычных друзей из 2, он видит 4. Я хочу вернуть только друзей из 2, которые не так дружат с 4.

У меня есть небольшая проблема, объясняя это.

И я попробовал этот код:

     SELECT
       *
    FROM
        users U
            INNER JOIN friends F
                ON ( U.id = F.id_exp AND F.id_des = :id )
                OR ( U.id = F.id_des AND F.id_exp = :id )
    WHERE
        (U.id <> :id_k
        AND F.active = 1) 

        AND NOT IN
(SELECT u.id,
      u.nom, u.prenom, u.avatar
    FROM users u
    INNER JOIN
    (
      SELECT id_exp, id_des
      FROM friends
      WHERE id_exp IN(:id_exp, :id_des)
        AND active = 1
      UNION
      SELECT id_des, id_exp
      FROM friends
      WHERE id_des IN(:id_exp, :id_des)
        AND active = 1
    ) tmp ON tmp.id_des = u.id
    GROUP BY u.id
    HAVING COUNT(*) = 2)

Но в худшем случае это не работает, выдает ошибки, и соответствующий раздел страницы не появляется. Спасибо.

1 ответ

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

  SELECT
       u.id
     , u.nom
     , u.prenom
     , case when count(tmp.id_des) = 1 then 'Not Mutual'
            when count(tmp.id_des) = 2 then 'Mutual'
            when count(tmp.id_des) = 0 then 'Alone in this world'
            else 'Undefined'
       end as friend_status
  FROM users u
  JOIN 
     ( SELECT id_exp
            , id_des
         FROM friends
        WHERE id_exp IN(:id_exp, :id_des)
          AND active = 1
        UNION
       SELECT id_des
            , id_exp
         FROM friends
        WHERE id_des IN(:id_exp, :id_des)
          AND active = 1
     ) tmp ON tmp.id_des = u.id 
    GROUP BY
       u.id
     , u.nom
     , u.prenom
Другие вопросы по тегам