0

私はこれら 2 つのステートメントを使用して BuddyPress に友情を照会していますが、これらの 2 つの 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

どのクエリからどの結果が得られたかを気にしない場合は、次の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

これは、へのシーケンシャル アクセスが多いため、2 つの結果セットのうちの 1つよりもわずかに効率的なindex_mergewhich (with ) を使用します。InnoDBUNIONwp_bp_friends

于 2012-05-30T18:37:39.987 に答える