【问题标题】:Mysql Inner join with OR condition?Mysql内部加入OR条件?
【发布时间】:2012-07-26 23:41:47
【问题描述】:

我有 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

如果位置值反之,则不会返回行。如何重写上述查询以产生预期结果?我应该在连接子句中包含 OR 条件吗?像下面这样?

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)

但是这个查询解释说“检查每条记录的范围”。 ..这是一种不好的做法吗?

结果

--------------------------------------------------------
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

【问题讨论】:

  • 你已经回答了自己的问题
  • 但第二个查询显示“检查每条记录的范围”。 ..这是一种不好的做法吗?
  • 本身不是; mysql只是告诉你它使用了范围访问方法,这意味着它找到了“no good index to use”,这确实是由于or。

标签: mysql subquery inner-join


【解决方案1】:

您可以使用LEFT JOIN 加入location_distance 表两次,然后使用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

【讨论】:

    猜你喜欢
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 2012-11-28
    相关资源
    最近更新 更多