0

我正在使用这两个语句来查询 BuddyPress 的友谊,但我想知道它们是否是一种更好的方法或组合这两个 MySQL 语句的方法:

    //Statement for friendship initiator
    $SQL1 = "SELECT wp_users.display_name AS'name', 
                    wp_users.user_login AS 'fname', 
                    wp_users.user_nicename AS 'surname' 
            FROM wp_users 
            INNER JOIN wp_bp_friends 
                  ON wp_users.id = wp_bp_friends.friend_user_id 
            WHERE 1=1 
               AND wp_bp_friends.initiator_user_id = " . $user_id . " 
               AND wp_bp_friends.is_confirmed = 1";


    //Statement for friendship non-initiator
    $SQL2 = "SELECT wp_users.display_name AS 'name', 
                    wp_users.user_login AS 'fname', 
                    wp_users.user_nicename AS 'surname' 
             FROM wp_users 
             INNER JOIN wp_bp_friends 
                   ON wp_users.id = wp_bp_friends.initiator_user_id 
             WHERE 1=1 
                   AND wp_bp_friends.friend_user_id = " . $user_id . " 
                   AND wp_bp_friends.is_confirmed = 1";

结果应该包含一个基于 $user_id 的友谊列表,无论他们是否发起了关系。

4

3 回答 3

2
$sql = "
  SELECT u.display_name  AS name,
         u.user_login    AS fname,
         u.user_nicename AS surname
  FROM   wp_users        AS u
    JOIN wp_bp_friends   AS f
      ON (u.id, $user_id) IN (
           (f.friend_user_id,    f.initiator_user_id),
           (f.initiator_user_id, f.friend_user_id)
         )
  WHERE  f.is_confirmed = 1
";

编辑

根据@Quassnoi下面的评论,与上面的答案一样优雅,它不会使用索引进行查找(由于 MySQL 实现缺陷)。相反,您可以这样做:

$sql = "
  SELECT u.display_name  AS name,
         u.user_login    AS fname,
         u.user_nicename AS surname
  FROM   wp_users        AS u
    JOIN wp_bp_friends   AS f
      ON (f.friend_user_id    = u.id AND f.initiator_user_id = $user_id)
      OR (f.initiator_user_id = u.id AND f.friend_user_id    = $user_id)
  WHERE  f.is_confirmed = 1
";
于 2012-05-30T18:33:52.697 回答
0

如果您不关心哪个结果来自哪个查询,那么您可以轻松地将它们与 a 结合起来UNION,如下所示:

$sql = "SELECT 
   wp_users.display_name AS 'name', 
   wp_users.user_login AS 'fname', 
   wp_users.user_nicename AS 'surname' 
FROM wp_users 
INNER JOIN wp_bp_friends ON wp_users.id = wp_bp_friends.friend_user_id 
WHERE 1=1 
AND wp_bp_friends.initiator_user_id = " . $user_id . " 
AND wp_bp_friends.is_confirmed = 1
UNION
SELECT 
   wp_users.display_name AS 'name', 
   wp_users.user_login AS 'fname', 
   wp_users.user_nicename AS 'surname' 
FROM wp_users 
INNER JOIN wp_bp_friends ON wp_users.id = wp_bp_friends.initiator_user_id 
WHERE 1=1 
AND wp_bp_friends.friend_user_id = " . $user_id . " 
AND wp_bp_friends.is_confirmed = 1";

如果它们来自哪个查询确实很重要,那么您可以为每个查询添加一个静态 varchar 列,以后可以使用它来确定该行来自哪个查询:

$sql = "SELECT 'FIRST', 
   wp_users.display_name AS 'name', 
   wp_users.user_login AS 'fname', 
   wp_users.user_nicename AS 'surname' 
FROM wp_users 
INNER JOIN wp_bp_friends ON wp_users.id = wp_bp_friends.friend_user_id 
WHERE 1=1 
AND wp_bp_friends.initiator_user_id = " . $user_id . " 
AND wp_bp_friends.is_confirmed = 1
UNION
SELECT 'SECOND',
   wp_users.display_name AS 'name', 
   wp_users.user_login AS 'fname', 
   wp_users.user_nicename AS 'surname' 
FROM wp_users 
INNER JOIN wp_bp_friends ON wp_users.id = wp_bp_friends.initiator_user_id 
WHERE 1=1 
AND wp_bp_friends.friend_user_id = " . $user_id . " 
AND wp_bp_friends.is_confirmed = 1";
于 2012-05-30T18:33:12.387 回答
0
SELECT  u.display_name, u.user_login, u.user_nicename
FROM    wp_bp_friends f
JOIN    wp_users u
ON      u.id =
        CASE @userId
        WHEN f.initiator_user_id THEN
                f.friend_user_id
        WHEN f.friend_user_id THEN
                f.initiator_user_id
        END
WHERE   (
        f.initiator_user_id = @userId
        OR
        f.friend_user_id = @userId
        )
        AND f.is_confirmed = 1

initiator_user_id在和上创建索引friend_user_id

这将使用index_mergewhich (with InnoDB) 比UNION两个结果集中的 a 稍微更有效,因为对wp_bp_friends.

于 2012-05-30T18:37:39.987 回答