2011-07-05 12 views
1

私は友人のテーブルに似たものを持っています。その名前はcontactsです。それはあります連絡先テーブルの問題

  • user_idは、その連絡先の所有者のようなものだユーザーのためのIDである、
  • contact_iduser_idと友達にあります、そのユーザーのIDです。

eventsという2番目のテーブルがあります。それは:

  • user_idは、そのイベントの作成者のIDです。

私の友人が作成したイベントを選択する必要があります。だから私が連絡先リストにJohnとAnnaを持っていれば...私はそれらの出来事を表示する必要があります。ここで

は、ソリューションです:

SELECT `bio_community_events`.`id`, 
     `bio_community_events`.`begin_on`, 
     `bio_community_events`.`name` 
    FROM `bio_community_events` 
    JOIN `bio_contacts` ON (`bio_contacts`.`contact_id` = `bio_community_events`.`user_id`) 
WHERE `bio_contacts`.`user_id` = '33' 

すなわち、私のIDは33です。それは私に私の友人の出来事を与えます。そして、ここに問題が来る...

私は私の友人と連絡を取る人ではない状況があります。その逆、アンナはそれをしました。このクエリは単にそれを無視し、Annaの結果を表示しません。

+0

なぜあなたはイベントの記録者ではなく、イベントの作成者に関係していますか? d自体? –

+0

「SELECT ... FROM bio_contacts」のように? – daGrevis

答えて

2
SELECT `bio_community_events`.`id`, 
     `bio_community_events`.`begin_on`, 
     `bio_community_events`.`name` 
    FROM `bio_community_events` 
    JOIN `bio_contacts` 
    ON (`bio_contacts`.`contact_id` = `bio_community_events`.`user_id`) 
WHERE `bio_contacts`.`user_id` = '33' 

UNION ALL         --- or UNION if this gives you 
              --- duplicate row 
SELECT `bio_community_events`.`id`, 
     `bio_community_events`.`begin_on`, 
     `bio_community_events`.`name` 
    FROM `bio_community_events` 
    JOIN `bio_contacts` 
    ON (`bio_contacts`.`user_id` = `bio_community_events`.`user_id`) 
WHERE `bio_contacts`.`contact_id` = '33' 

かのように例#1の行が返されます。

(SELECT ...) 
UNION ALL 
(SELECT ...) 

ORDER BY ?  --- optional 
LIMIT x ; 

ORDER BYを使用すると、このようなクエリでかなりのコストがかかる可能性があります。 EXISTSを使用している

(SELECT ... 
    ORDER BY ? 
    LIMIT a 
) 
UNION ALL 
(SELECT ... 
    ORDER BY ? 
    LIMIT b 
) 

LIMIT x ;   --- with or without this LIMIT 

元の問題を解決するための別の方法:

SELECT `bio_community_events`.`id`, 
     `bio_community_events`.`begin_on`, 
     `bio_community_events`.`name` 
    FROM `bio_community_events` 
    WHERE EXISTS 
     (SELECT * 
      FROM `bio_contacts` 
     WHERE `bio_contacts`.`user_id` = '33' 
      AND `bio_contacts`.`contact_id` = `bio_community_events`.`user_id` 
    ) 
    OR EXISTS 
     (SELECT * 
      FROM `bio_contacts` 
     WHERE `bio_contacts`.`contact_id` = '33' 
      AND `bio_contacts`.`user_id` = `bio_community_events`.`user_id` 
    ) 

か:

SELECT `bio_community_events`.`id`, 
     `bio_community_events`.`begin_on`, 
     `bio_community_events`.`name` 
    FROM `bio_community_events` 
    WHERE EXISTS 
     (SELECT * 
      FROM `bio_contacts` 
     WHERE (`bio_contacts`.`user_id` = '33' 
      AND `bio_contacts`.`contact_id` = `bio_community_events`.`user_id`) 
      OR (`bio_contacts`.`contact_id` = '33' 
      AND `bio_contacts`.`user_id` = `bio_community_events`.`user_id`) 
    ) 
また、インデックスを使用することができ、この(別の)クエリを持つことができます

あなたの計画がfiの場合最も効率的なクエリーを実行し、正しく動作するすべてのものを試してみましょう(INを使用し、UNIONを使用し、EXISTSを使用) - コースから外したいORDER BYを追加し、スピードと実行計画を確認してください。

I少なくとも有するであろう:

  • 表にbio_community_events
    • ORDER BY

ために使用するフィールド(単数または複数)にuser_id

  • 索引の索引および

    テーブルbio_contacts
    • 、2つの複合インデックス (contact_id, user_id)
      • (user_id, contact_id)

  • そして、あなたはそれがXミリ秒未満で実行させることができない場合(別の質問を投稿しますあなたの上司が決めたX:

  • +0

    例#1の返されたすべての行に制限を設定するにはどうすればよいですか? – daGrevis

    +0

    @daGrevis:更新された回答をご覧ください。 –

    +0

    *高速な方法はありますか?私の上司は、このクエリーはうまくいかないと言っていました。なぜなら、何百万ものエントリがあると、実行に多くの時間がかかるからです。そうですか? – daGrevis

    0

    あなたは同様にあなたの友人のユーザーIDを取得する必要があります:すべての制限を設定するには

    SELECT `bio_community_events`.`id`, 
         `bio_community_events`.`begin_on`, 
         `bio_community_events`.`name` 
        FROM `bio_community_events` 
        JOIN 
        (SELECT `bio_contacts`.`contact_id` AS id 
         FROM `bio_contacts` 
         WHERE `bio_contacts`.`user_id` = '33' 
        UNION ALL        
         SELECT `bio_contacts`.`user_id` AS id 
         FROM `bio_contacts`         
         WHERE `bio_contacts`.`contact_id` = '33' 
        ) AS un 
        ON (un.id = `bio_community_events`.`user_id`) 
    

    へ:

    SELECT `bio_community_events`.`id`, `bio_community_events`.`begin_on`, `bio_community_events`.`name` 
    FROM `bio_community_events` 
    JOIN `bio_contacts` 
        ON (`bio_contacts`.`contact_id` = `bio_community_events`.`user_id`) 
    WHERE `bio_contacts`.`user_id` = '33' 
    OR `bio_contacts`.`user_id` IN (SELECT `contact_id` FROM `contacts` WHERE `user_id` = 33) 
    
    +0

    [Err] 1052 - where句のカラム 'user_id'があいまいです。 – daGrevis

    +0

    そのエラーを修正しました。 2番目の選択で間違ったテーブル名。とにかく、このクエリは前と同じ結果を返します。 – daGrevis

    +0

    さて、あなたのテーブルは「連絡先」という名前か、それともbio_contactsですか? – Candide

    1
    SELECT id, begin_on, name 
    FROM bio_community_events 
    WHERE user_id IN (SELECT user_id FROM bio_contacts WHERE contact_id = '33') 
    OR user_id IN (SELECT contact_id FROM bio_contacts WHERE user_id = '33') 
    
    +0

    これは私にも私の出来事を与えてくれます。 – daGrevis

    +0

    あなたのお友達イベントのみをお贈りしますか?もし私が私の例を編集した場合 –

    +0

    はい、私は友達のイベントだけを欲しいです。自分ではない。他に誰もいません。あなたが編集した例題は非常に奇妙です。同じエントリを12回返します。 – daGrevis

    関連する問題