【问题标题】:Building A Basic Friends System: Get All Friends Query搭建基础好友系统:获取所有好友查询
【发布时间】:2012-01-08 23:00:41
【问题描述】:

所以我有这两张表:

user table:
id, username
10, hovercraft
11, mine_craft

friendship table:
id, user_id, friend_id
1,  10,      11

现在我有了这个 SQL 查询:

SELECT `friends`.`id`, 
 `friends`.`username`, 
FROM `users` AS `u` 
JOIN `friendships` AS `fs` 
ON (`fs`.`user_id` = `u`.`id`) 
JOIN `users` AS `friends` 
ON (`friends`.`id` = `fs`.`friend_id`) 
WHERE `fs`.`user_id` = '10' 
OR  `fs`.`friend_id` = '10'

我想在哪里获得特定 user_id 的朋友。但是,此查询无法创建“双向”检索,因为当我提供 user_id 11 时,没有朋友出现。

有没有办法解决这个问题?

编辑:我忘了添加friend_id也引用了用户表中的id

【问题讨论】:

    标签: mysql sql database-design


    【解决方案1】:

    已添加,更好的版本(我认为):

    select u.id, username
    from user u
    left join friendship f1 on u.id = f1.user_id
    left join friendship f2 on u.id = f2.friend_id
    where coalesce(f1.friend_id, f2.user_id, u.id) <> u.id and
        coalesce(f1.friend_id, f2.user_id, u.id) = 10
    

    比这个查询(放在第一位):

    select id, username from (
        select u.id, username, case when f.friend_id <> u.id then f.friend_id else f.user_id end as friend_id
        from user u
        join friendship f on u.id = f.user_id
        union
        select u.id, username, case when f.friend_id <> u.id then f.friend_id else f.user_id end as friend_id
        from user u
        join friendship f on u.id = f.friend_id
    ) t where friend_id = 10
    

    【讨论】:

    • 这很棒,虽然这是我第一次使用 COALESCE。我会花时间研究它:D
    【解决方案2】:

    您的查询开始得太深了。由于friendships 表有一个字段,您可以在其中查找用户ID,然后从那里开始查询并仅加入users 表以选择朋友:

    SELECT u."id", u."username"
    FROM "friendships" AS f
    JOIN "users" AS u ON f.friend_id = u."friend_id"
    WHERE f."user_id" = 11
    

    【讨论】:

      【解决方案3】:

      这是我的解决方案:困难在于正确的请求,因为可以跨越好友请求(如果 A 询问 B 或 B 询问 A,则将相反的方式存储在表的“to”和“from”字段中) .让我们这样做,用户 UNION 和别名可以独立于下面的关系表从任何用户那里获取朋友。

      1. [friends] 表(关系):to|from|statut(pending,confirmed)
      2. “to”和“from” > [users] 表的 foreign_keys 约束

      下面的请求总是给出想要的结果! (将 %d 替换为 SESSION 中的用户 ID 或用户 ID

      SELECT
          users.userNickname,
          friends.to AS friendUser,
          friends.from AS currentUser,
          friends.statut
          FROM
          users
              INNER JOIN
              friends
              ON
              users.userId = friends.to
          WHERE
          friends.from = '%d' 
      UNION
          SELECT
          users.userNickname,
          friends.from AS friendUser,
          friends.to AS currentUser,
          friends.statut
          FROM
          users
              INNER JOIN
              friends
              ON
              users.userId = friends.from
          WHERE
          friends.to = '%d'
      

      【讨论】:

        猜你喜欢
        • 2015-06-02
        • 1970-01-01
        • 2011-08-16
        • 1970-01-01
        • 2017-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多