web-dev-qa-db-ja.com

Mysql内部結合OR条件?

私は以下のような2つのテーブルを持っています

location_distance

----------------------------------------------
id   | fromLocid    | toLocid   |  distance
----------------------------------------------
1    |  3           |  5        |   70
2    |  6           |  8        |   15
3    |  2           |  4        |   63
...

other_table

--------------------------------------------
Id  | fromLocid   | toLocid    | otherdata
--------------------------------------------
12  |  5          | 3          | xxxx
22  |  2          | 4          | xxxx   
56  |  8          | 6          | xxxx
78  |  3          | 5          | xxxx

各行のother_tableの場所との距離を取得したいと思います。これが私が試したことです

SELECT ot.*, ld.distance FROM other_table AS ot 
    INNER JOIN location_distance ld ON ld.fromLocid = ot.fromLocid AND ld.toLocid = ot.toLocid

場所の値がその逆の場合、これは行を返しません。上記のクエリを書き直して、期待される結果を生成するにはどうすればよいですか? [〜#〜]または[〜#〜]結合句の条件を含める必要がありますか?以下のように?

SELECT ot.*, ld.distance FROM other_table AS ot 
    INNER JOIN location_distance ld ON (ld.fromLocid = ot.fromLocid OR ld.fromLocid = ot.toLocid) AND (ld.toLocid = ot.fromLocid OR ld.toLocid = ot.fromLocid)

ただし、このクエリExplainは「各レコードの範囲をチェックしました」と表示します。.これは悪い習慣ですか?

結果

--------------------------------------------------------
Id  | fromLocid | toLocid    | otherdata   | distance
--------------------------------------------------------
22  |  2        |   4        | xxxx        | 63
78  |  3        |   5        | xxxx        | 70

期待される結果はである必要があります

-----------------------------------------------------
Id  | fromLocid   | toLocid   | otherdata  | distance
-----------------------------------------------------
12  |   5         |    3      | xxxx       | 70
22  |   2         |    4      | xxxx       | 63
56  |   8         |    6      | xxxx       | 15 
78  |   3         |    5      | xxxx       | 70
14
jane

_location_distance_を使用して_LEFT JOIN_テーブルに2回参加し、次にCOALESCE()関数を使用してdistanceの正しい値を返すことができます。

_select ot.id,
  ot.fromlocid,
  ot.tolocid,
  ot.otherdata,
  coalesce(ld1.distance, ld2.distance) distance
from other_table ot
left join location_distance ld1
  on ld1.fromLocid = ot.toLocid
  and ld1.toLocid = ot.fromLocid 
left join location_distance ld2
  on ld2.toLocid = ot.toLocid
  and ld2.fromLocid = ot.fromLocid 
_

SQL Fiddle with Demo を参照してください

これにより、次の結果が返されます。

_| ID | FROMLOCID | TOLOCID | OTHERDATA | DISTANCE |
---------------------------------------------------
| 12 |         5 |       3 |      xxxx |       70 |
| 22 |         2 |       4 |      xxxx |       63 |
| 56 |         8 |       6 |      xxxx |       15 |
| 78 |         3 |       5 |      xxxx |       70 |
_
8
Taryn

距離テーブルを次のように2回結合する方がおそらく高速です。

INNER JOIN location_distance ld1 ON ld1.fromLocid = ot.fromLocid AND ld1.toLocid = ot.toLocid
INNER JOIN location_distance ld2 ON ld2.toLocid = ot.fromLocid AND ld2.fromLocid = ot.toLocid

次に、IFを使用して、どちらを選択するかを決定します

IF(ld1.fromLocid, ld1.distance, ld2.distance) as distance
3
Vatev