2012-03-07 3 views
5

私はテーブルuserslocationsとジョインテーブルを持っています。ジョイン・テーブルには、その場所の各個人のランク値もあります。これらの個人は、特定の場所で他の場所より高いランクを持つためです。Joinテーブルに存在しない値を表示するには、どのようなJoin?

users 
========= 
id | name 
========= 
1 | john 
2 | bob 
3 | alex 

locations 
=============== 
id | name 
=============== 
1 | san diego 
2 | dallas 
3 | new york 
4 | denver 

join_users_locations 
============================== 
user_id | location_id | rank 
============================== 
     2 |   1 | 4 
     2 |   2 | 3 
     2 |   4 | 2 
     3 |   1 | 2 
     3 |   2 | 4 

参加表には、その場所にランクがあるユーザーだけがリストされています。彼らのランクがゼロ/ヌルであれば、テーブルにいなくてもよい。

私はこのようなクエリ結果を取得したいよ:ちょうど与える(

name | location | rank 
======================= 
bob | san diego | 4 
bob | dallas | 3 
bob | new york | 0 
bob | denver | 2 

あなたが見ることができるように、私はすべての場所がリストになりたい、ユーザーがで接合されていないものも含めをそれらのフィールドはゼロのランク値)。

それは場所のリストを取得するのは簡単ですし、彼/彼女はと接合された場所のためのランク:

SELECT 
    u.name, 
FROM users u 
LEFT JOIN join_users_locations jul ON jul.user_id = u.id 
LEFT JOIN locations l ON l.id = jul.location_id 
WHERE u.id = 2 

しかし、唯一のリストはどのような場所ユーザーがと接合されています。私は参加していない場所も見たいと思う。

これは可能ですが、解決策がわかりません。私はいくつかの異なるタイプのJOINをさまざまな結果で試しました。

SQL FIDDLE HERE

+0

あなたは参加外側左しようとしましたか? – Ciprian

答えて

3

あなたはusersからlocationsCROSS JOINでこれを行うことができます。

SELECT 
    u.name, 
    l.name AS location, 
    IFNULL(jul.rank, 0) AS rank 
FROM 
    users u CROSS JOIN 
    locations l LEFT JOIN 
    join_users_locations jul 
     ON jul.user_id = u.ID 
     AND jul.location_id = l.id 
WHERE u.id = 2 
+1

ああ興味深い...前にクロスジョインを使ったことはありません。これは完全にここで働いています:http://sqlfiddle.com/#!2/4a46a/8ありがとう –

0

参加。外側の結合には、左側に対応するタプルがない場合でも、結合の「左側」のすべてが含まれます。あなたはおそらく、0の代わりにnullを取得します。それは大丈夫ですか? (あなたがいない場合は、0にNULL値表示を設定することができます)

+1

このようにしますか? http://sqlfiddle.com/#!2/4a46a/4それを動作させることはできません。 –

+1

あなたが挿入したすべての値にはランクがあります。私がインサートのいずれかを変更してランクをヌルにして、それを再実行すれば、あなたが望むものを正確に得ることができます。 0の代わりに空白を除いてhttp://sqlfiddle.com/#!2/9f52c/2 – Colleen

+0

私はフォローしていません。 SQL FiddleのURLをコピー/ペーストできますか? –

0
SELECT u.name,l.name as location,jul.rank 
FROM users u,locations l,join_users_locations jul 
WHERE u.id = jul.user_id AND 
     jul.location_id = l.id AND 
     u.id = 2 
UNION 
SELECT 'bob' AS NAME,A.NAME AS location,A.RANK_NULL AS RANK 
FROM 
(SELECT *,IFNULL(RANK,0) AS RANK_NULL 
FROM (SELECT * FROM JOIN_USERS_LOCATIONS JUL WHERE JUL.USER_ID=2)JUL 
RIGHT JOIN LOCATIONS L 
    ON JUL.LOCATION_ID = L.ID 
WHERE RANK IS NULL)A 

OR

SELECT IFNULL(JUL.NAME,'bob'),L.NAME,IFNULL(RANK,0) AS RANK 
FROM (SELECT U.NAME,JUL.USER_ID,JUL.LOCATION_ID,JUL.RANK 
     FROM USERS U,JOIN_USERS_LOCATIONS JUL 
     WHERE U.ID=JUL.USER_ID AND JUL.USER_ID=2 
    ) JUL 
     RIGHT JOIN 
     LOCATIONS L 
    ON JUL.LOCATION_ID = L.ID 
+0

where節の暗黙的な結合は、内部結合を行うのと同じ効果を持ちます... jul.rankは決してnullにはなりませんが、これは、ユーザーが 'join_user_locations'にレコードを持っていない場所を返すことはできません... –

+0

これは非常に複雑です... – Teja

関連する問題