2016-05-18 27 views
1

私はこのクエリを持っている:条件に基づいて2つのテーブルを結合する方法は?

SELECT (CASE WHEN A.name IS NULL THEN B.name ELSE A.name END) 
FROM mytable A LEFT JOIN mytable B ON (A.related=B.id) 

それは動作しますが、JOINは常に起こることを、私はJOINはこれら2例のために発生していることを意味する:

  • WHEN A.name IS NULL THEN B.name
  • ELSE A.name

私はそれを避けたい。私はこの条件のためにJOINを実行したいという意味ですWHEN A.name IS NULLいつもではありません(私の目的は役に立たない結合を避ける)。どうやってやるの?

+0

"役に立たない参加"とは具体的にはどういう意味ですか? – Uueerdo

+0

「A.nameがNULLである」が* true *ではない場合、 'JOIN'は必要ありません。 – stack

答えて

1

私は、これは任意のより効率的であるわからないんだけど、技術的にcorrelated subqueryを使用すると、余分なjoinを削除します:

SELECT 
    CASE WHEN name IS NULL 
    THEN (SELECT name FROM mytable B WHERE A.related = b.id) 
    ELSE A.name 
    END 
FROM mytable A 

詳細情報:Which one is faster: correlated subqueries or join?

+0

いいね...ありがとう。 upvote – stack

+0

短い質問ですが、そのサブクエリは 'name IS NULL'が* true *でないときに実行されますか? – stack

+0

また、私のクエリの「JOIN」はどうですか? 'name is NULL'が* true *でないときに実行されますか? – stack

1

あなたは本当に部分的に参加を避けることはできません。しかし、元の結合を行うほうがおそらく速いでしょう。なぜなら、これはすべて、行の比較ごとに計算された条件に加算される可能性が高いからです。

SELECT (CASE WHEN A.name IS NULL THEN B.name ELSE A.name END) 
FROM mytable A 
LEFT JOIN mytable B ON A.name IS NULL AND A.related=B.id 
; 

これは技術的には避けることができますが、私はそれがより高速になることは間違いありません。

SELECT A.name 
FROM mytable A 
WHERE A.name IS NOT NULL 
UNION 
SELECT B.name 
FROM mytable A 
LEFT JOIN mytable B ON A.related=B.id 
WHERE A.name IS NULL 
; 

編集:考え直しでは、非常に大きなデータセットに、これは有用である可能性が何かあるかもしれません。それでもそのようなシナリオでは、テーブルの内容全体を選択する可能性は低いです。

+0

Oh .. 'ON'節に' A.name IS NULL'を追加するのはどうにかして巧妙です..ありがとうございます。 upvote。 – stack

+0

正直言って、私はあなたの2番目の質問が嫌いです。私が知りたいのは、どれがあなたが選ぶだろうか?あなたの最初のクエリ?あなたの2番目のクエリ?質問の私の質問? – stack

+0

@stack私が最初の文で言ったように、MySQLクエリオプティマイザがどのようにそれを処理するかによって、条件を追加すると行の比較が妨げられず、すべての行の比較に余分な操作が追加される可能性があります。 – Uueerdo

1
SELECT COALESCE(A.name, B.name) AS name 
FROM mytable A 
LEFT JOIN mytable B ON (A.related=B.id AND A.name IS NULL) 
+0

ニース... upvote – stack

+0

ときどき私たちは考え抜いています。 –

関連する問題