2012-05-30 4 views
0

J'utilise ces deux déclarations à BuddyPress interroger pour l'amitié, mais je me demande si leur est une meilleure façon ou d'une façon de combiner ces deux déclarations MySQL:Comment combiner ces deux états 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"; 

Le Le résultat devrait contenir une liste d'amitiés basée sur $ user_id, peu importe s'ils ont initié la relation ou pas.

Répondre

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 
"; 

EDIT

par @Quassnoi's comment ci-dessous, aussi élégante que la réponse ci-dessus est, il ne sera pas utiliser d'index pour les recherches (en raison d'un défaut de mise en œuvre MySQL). Au lieu de cela, vous pouvez faire:

$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 
"; 
+0

Comment indice hostile! – Quassnoi

+0

@Quassnoi: Oh oui, nous revenons au point d'hier: j'avais déjà oublié. Pouah. On pourrait faire exploser le 'IN' dans les clauses explicites' ... OR ... 'pour être plus convivial. Je vais mettre à jour ma réponse. – eggyal

+0

Merci! Cela a fonctionné comme un charme, et a augmenté mes points d'éducation, aussi! – Auzzy

0

Si vous ne se soucient pas quel résultat est venu à partir de laquelle la requête, vous pouvez facilement les combiner avec un UNION, comme suit: Si tel est le sujet qui demande ils sont

$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"; 

de, vous pouvez ajouter une colonne varchar statique pour chaque requête que vous pouvez utiliser plus tard pour savoir quelle interrogation de la ligne est provenu

$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"; 
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 

Créer les index initiator_user_id et friend_user_id.

Cela utilisera index_merge qui (avec InnoDB) est légèrement plus efficace qu'un UNION de deux resultsets, en raison de plus accès séquentiel à wp_bp_friends.

Questions connexes