私は以下のような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
_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 |
_
距離テーブルを次のように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