基于多列联接两个表的更好方法

时间:2019-11-26 17:00:14

标签: sql sql-server tsql

我有两个桌子

Table1

    id |   Name   | Car     |  
    ---+----------+---------+
     1 |   Jake   |   BMW     |
     2 |   Smith  |   Audi    | 
     3 |   Jake   |   Benz    | 
     4 |   Jake   |   Tesla   | 
     5 |   Jake   |   Jaguar  |  
     6 |   Smith  |   Toyoyta | 
     7 |   Andrew |   Bike    |
     8 |   Jake   |   BMW     | 

和 表2

    id |   Name   | Car1    | Car2    | Car3     |  Car3    |
    ---+----------+---------+---------+----------+----------+
     1 |   Jake   | Nissan  |  BMW    |  Tesla   | Jaguar   |
     2 |   Smith  | Audi    |  Toyota |   Ford   |          |
     3 |   Andrew | Bike    |  BMW    |   Jaguar |  Prius   |

我想首先基于[Table1]和[Table2]中的 Name 以及 [Table1.Car]与[ Table2.Car1] [Table1.Car2]与[Table2.Car1] [Table1.Car]与[Table2.Car3]

因此,例如,Jake的JOIN会返回以下内容,因为Jake在[Table2]中没有日产。

    id |   Name   | Car2    | Car3    |  Car3   |
    ---+----------+---------+---------+---------+
     1 |   Jake   |   BMW   |  Tesla  |  Jaguar |

我在下面尝试了INNER JOIN

select DISTINCT(a.Name) from Table1 a
JOIN Table2 b ON a.Name = b.Name 
AND b.Car1 = a.Car OR b.Car2 = a.Car OR b.Car3 = b.Car 
where b.Name='Jake' 

此结果返回一些列,但它不会打印出所有匹配的列,我怀疑是因为OR条件。

是否有更好的方法来达到上述效果?

2 个答案:

答案 0 :(得分:0)

我认为您缺少一些括号:

select DISTINCT(a.Name) from Table1 a
JOIN Table2 b ON a.Name = b.Name 
AND (b.Car1 = a.Car OR b.Car2 = a.Car OR b.Car3 = b.Car)
where b.Name='Jake' 

AND是比OR更高的优先级,因此您的查询对此进行评估:

select DISTINCT(a.Name) from Table1 a
JOIN Table2 b ON
(a.Name = b.Name AND b.Car1 = a.Car)
OR b.Car2 = a.Car OR b.Car3 = b.Car
where b.Name='Jake' 

可能不是您想要的。

答案 1 :(得分:0)

要同时打印Table2中的所有列,则还需要SELECT

SELECT DISTINCT a.*, b.*
FROM Table1 a
LEFT JOIN Table2 b 
  ON a.Name = b.Name
 AND a.Car IN (b.Car1, b.Car2, b.Car3)
WHERE a.Name='Jake'

为此,也可以使用IN

LEFT JOIN将显示Table1中的所有内容,即使与Table2不匹配也是如此。
然后WHERE子句查找a.Name,而不是b.Name
否则它将表现为INNER JOIN

但是,如果您要在表1中查找每个名称缺少的汽车的记录,那么

然后,您可以过滤b.Name IS NULL,以查找不匹配的内容。

SELECT a.Name, a.Car
FROM Table1 a
LEFT JOIN Table2 b 
  ON a.Name = b.Name
 AND a.Car IN (b.Car1, b.Car2, b.Car3)
WHERE a.Name='Jake'
  AND b.Name IS NULL
GROUP BY a.Name, a.Car