【问题标题】:Friendship System Sql Structure & Query友谊系统Sql结构与查询
【发布时间】:2010-12-30 00:32:14
【问题描述】:

我正在编写一个友谊系统,它有两个表。

成员

  • 身份证
  • 用户名
  • 密码

朋友

  • 身份证
  • user_id
  • friend_id
  • 状态

假设我想要一个可以选择成员 $userId 的朋友 ID 的查询,如何在一个查询中完成此操作?

我找到了一个解决方案,即进行 2 次查询。第一个选择朋友 WHERE user_id = $userId,第二个选择朋友 WHERE friend_id = $userId,然后将它们混合在一个数组中。如果没有其他解决方案,我将使用它。

请对 SQL 结构和查询有任何想法?

【问题讨论】:

    标签: php sql mysql join


    【解决方案1】:

    用途:

    SELECT f.friend_id
      FROM FRIENDS f
     WHERE f.user_id = $user_id
    UNION
    SELECT t.user_id
      FROM FRIENDS t
     WHERE t.friend_id = $user_id
    

    使用UNION 将删除重复项。 UNION ALL 会更快,但它不会删除重复项。

    如果您想从MEMBERS 表中获取朋友的信息,请使用:

    SELECT m.*
      FROM MEMBERS m
      JOIN (SELECT f.friend_id 'user_id'
              FROM FRIENDS f
             WHERE f.user_id = $user_id
            UNION
            SELECT t.user_id
              FROM FRIENDS t
             WHERE t.friend_id = $user_id) x ON x.user_id = m.id
    

    顺便说一句:我希望您在变量上使用mysql_escape_string,否则您将面临 SQL 注入攻击的风险:

    【讨论】:

    • 您的代码正是我所需要的!非常感激。接受你的回答。
    • function safeDB($text){ return mysql_real_escape_string(strip_tags(trim($text))); } 我相信这很好:)
    • @amindzx:很酷,只是检查一下。有些人对 SQL 注入攻击很着迷
    【解决方案2】:

    你应该可以尝试使用

    SELECT  m.*
    FROM    friends f INNER JOIN
            members m ON f.friend_id = m.user_id
    WHERE   f.user_id = $userId
    

    这将为您提供所有朋友详细信息

    两个都看一下

    SELECT  DISTINCT CASE WHEN f.user_id = $userId then f.friend_id else f.user_id END CASE
    FROM    friends f 
    WHERE   f.user_id = $userId
    OR      f.friend_id = $userId
    

    【讨论】:

    • 这看起来很复杂,但我会尝试一下。谢谢,你能推荐任何好的资源来了解这个吗?
    • 这是非常标准的 Sql。您需要 Sql 帮助吗?
    • #1054 - 'on 子句'中的未知列 'master.user_id'
    • 再看一遍...抱歉,自动完成功能在那儿弄坏了。
    • @amindzx:因为列是id,而不是MEMBERS 表中的user_id。 @astander:希望你不介意我编辑了你的答案来纠正这个问题。
    【解决方案3】:

    为什么不为 1 个友谊插入 2 行。例如:

    假设我们有 2 个用户将成为朋友

    用户 ID : 1 & Friend_id : 2

    insert into friends (user_id, friend_id, status) values (1,2,0)    
    insert into friends (user_id, friend_id, status) values (2,1,0)
    

    因此您可以通过简单的选择查询轻松选择。

    它还可以减轻您可能会问的下一个问题“如何找到共同的朋友”的痛苦。

    【讨论】:

      【解决方案4】:

      因为你要求的东西很简单,比如:

      SELECT friend_id FROM friends WHERE user_id = id; [fill in the id]
      

      我会给你一些更花哨的东西:

      SELECT * FROM members AS m
      WHERE m.id
      IN (SELECT f.friend_id FROM friends AS f
        WHERE f.user_id = (SELECT pm.id FROM members AS pm
          WHERE pm.username = 'amindzx'));
      

      在子查询上使用连接会更好。

      此外,朋友列中不需要id,因为user_idfriend_id 之间应该只存在一种关系;这些都可以被描述为id 列。

      【讨论】:

      • 你对ID完全正确,但是如果friend_id也链接到user_id而不重复,这个查询是否可以得到?我的意思是倒数。
      • 我很想回答你的问题,但我不明白你的意思。 “逆”是指您想找到所有拥有特定朋友的用户吗?这看起来像 select user_id from friends where friend_id = 1(假设 1 = 相关用户的 id)。