这有点复杂,但我有2张桌子.假设结构是这样的:
*Table1*
ID
PhoneNumber1
PhoneNumber2
*Table2*
PhoneNumber
SomeOtherField
Run Code Online (Sandbox Code Playgroud)
可以基于Table1.PhoneNumber1 - > Table2.PhoneNumber或Table1.PhoneNumber2 - > Table2.PhoneNumber来连接表.
现在,我想得到一个结果集,其中包含PhoneNumber1,SomeOtherField,它对应于PhoneNumber1,PhoneNumber2和SomeOtherField,对应于PhoneNumber2.
我想到了两种方法 - 通过两次加入表,或者在ON子句中加入OR一次.
方法1:
SELECT t1.PhoneNumber1, t1.PhoneNumber2,
t2.SomeOtherFieldForPhone1, t3.someOtherFieldForPhone2
FROM Table1 t1
INNER JOIN Table2 t2
ON t2.PhoneNumber = t1.PhoneNumber1
INNER JOIN Table2 t3
ON t3.PhoneNumber = t1.PhoneNumber2
Run Code Online (Sandbox Code Playgroud)
这似乎有效.
方法2:
以某种方式有一个看起来有点像这样的查询 -
SELECT ...
FROM Table1
INNER JOIN Table2
ON Table1.PhoneNumber1 = Table2.PhoneNumber OR
Table1.PhoneNumber2 = Table2.PhoneNumber
Run Code Online (Sandbox Code Playgroud)
我还没有得到这个工作,我不确定是否有办法做到这一点.
实现这一目标的最佳方法是什么?这两种方式都不简单或直观......有没有更简单的方法来做到这一点?这个要求一般如何实施?
Pau*_*sik 136
首先,我会尝试重构这些表,以避免使用电话号码作为自然键.我不是自然键的粉丝,这是一个很好的例子.自然键,尤其是电话号码之类的东西,可以随时更改.发生更改时更新数据库将是一个巨大的,容易出错的问题.*
你描述的方法1是你最好的选择.由于命名方案和短别名,它看起来有点简洁,但是......在多次连接同一个表或使用子查询等时,别名是你的朋友.
我会稍微清理一下:
SELECT t.PhoneNumber1, t.PhoneNumber2,
t1.SomeOtherFieldForPhone1, t2.someOtherFieldForPhone2
FROM Table1 t
JOIN Table2 t1 ON t1.PhoneNumber = t.PhoneNumber1
JOIN Table2 t2 ON t2.PhoneNumber = t.PhoneNumber2
Run Code Online (Sandbox Code Playgroud)
我做了什么:
*DBA避免更新自然键的麻烦的一种方法是不指定主键和外键约束,这进一步加剧了db设计不佳的问题.我实际上经常看到这个.
您可以使用UNION组合两个连接:
SELECT Table1.PhoneNumber1 as PhoneNumber, Table2.SomeOtherField as OtherField
FROM Table1
JOIN Table2
ON Table1.PhoneNumber1 = Table2.PhoneNumber
UNION
SELECT Table1.PhoneNumber2 as PhoneNumber, Table2.SomeOtherField as OtherField
FROM Table1
JOIN Table2
ON Table1.PhoneNumber2 = Table2.PhoneNumber
Run Code Online (Sandbox Code Playgroud)
除非Phone1或(更可能是)phone2可以为null,否则第一个是好的。在这种情况下,您要使用左联接而不是内部联接。
当您有一个包含两个电话号码字段的表时,通常这是一个不好的信号。通常,这意味着您的数据库设计存在缺陷。