这有点复杂,但我有 2 张 table 。假设结构是这样的:

*Table1*
ID
PhoneNumber1
PhoneNumber2

*Table2*
PhoneNumber
SomeOtherField

这些表可以基于 Table1.PhoneNumber1 -> Table2.PhoneNumber 或 Table1.PhoneNumber2 -> Table2.PhoneNumber 进行连接。

现在,我想获得一个结果集,其中包含 PhoneNumber1、对应于 PhoneNumber1、PhoneNumber2 的 SomeOtherField 和对应于 PhoneNumber2 的 SomeOtherField。

我想到了两种方法来做到这一点 - 要么在表上加入两次,要么在 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

这似乎有效。

方法 2 :

以某种方式有一个看起来像这样的查询 -
SELECT ...
FROM Table1
INNER JOIN Table2
   ON Table1.PhoneNumber1 = Table2.PhoneNumber OR
      Table1.PhoneNumber2 = Table2.PhoneNumber

我还没有让它起作用,我不确定是否有办法做到这一点。

实现这一目标的最佳方法是什么?两种方法都看起来简单或直观......有没有更直接的方法来做到这一点?这个要求一般是如何实现的?

最佳答案

首先,我会尝试重构这些表,以避免使用电话号码作为自然键。我不喜欢自然键,这是一个很好的例子。自然键,尤其是电话号码之类的东西,可以经常更改。在发生这种变化时更新您的数据库将是一个巨大的、容易出错的头痛问题。 *

方法 1 正如你所描述的,它是你最好的选择。由于命名方案和短别名,它看起来有点简洁,但是......在多次加入同一个表或使用子查询等时,别名是你的 friend 。

我只想清理一下:

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

我做了什么:
  • 无需指定 INNER - 这暗示您未指定 LEFT 或 RIGHT
  • 不要给你的主查找表添加 n 后缀
  • N-后缀您将多次使用的表别名以使其显而易见

  • * DBA 避免更新自然键的麻烦的一种方法是不指定主键和外键约束,这进一步加剧了数据库设计不佳的问题。我实际上经常看到这种情况。

    关于sql - 在同一张 table 上加入两次的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4267929/

    10-13 08:17