以第三个 Table 为条件加入两个 Table

Join Two Tables Conditioned on a Third Table

我正在尝试根据第三个表的条件创建两个表的视图。我有三个表:

客户

+-----------+------------+
| client_id | first_name |
+-----------+------------+
|  10000000 | Samantha   |
|  10000001 | Andrew     |
|  10000002 | Audrey     |
+-----------+------------+

地址

+-----------+------------------+---------------+-----------+
| client_id |    account_id    |    street     |   city    |
+-----------+------------------+---------------+-----------+
|  10000000 | AAAAAAAAAAAAAAAA | 123 Apple St  | Brussels  |
|  10000000 | BBBBBBBBBBBBBBBB | 111 Orange St | Hong Kong |
|  10000001 | CCCCCCCCCCCCCCCC | 456 Grape St  | Amsterdam |
|  10000002 | DDDDDDDDDDDDDDDD | 789 Peach St  | Toronto   |
+-----------+------------------+---------------+-----------+

帐户

+-----------+------------------+-----------+
| client_id |    account_id    |  status   |
+-----------+------------------+-----------+
|  10000000 | AAAAAAAAAAAAAAAA | cancelled |   <-- i do not want this record
|  10000000 | BBBBBBBBBBBBBBBB | active    |
|  10000001 | CCCCCCCCCCCCCCCC | active    |
|  10000002 | DDDDDDDDDDDDDDDD | active    |
+-----------+------------------+-----------+

我正在尝试实现如下所示的输出:

+-----------+------------+------------------+---------------+-----------+
| client_id | first_name |    account_id    |    street     |   city    |
+-----------+------------+------------------+---------------+-----------+
|  10000000 | Samantha   | BBBBBBBBBBBBBBBB | 111 Orange St | Hong Kong |
|  10000001 | Andrew     | CCCCCCCCCCCCCCCC | 456 Grape St  | Amsterdam |
|  10000002 | Audrey     | DDDDDDDDDDDDDDDD | 789 Peach St  | Toronto   |
+-----------+------------+------------------+---------------+-----------+

我无法提取结果。我最终得到了 Samantha 的两条记录。这是我最近的查询工作;我做错了什么?

SELECT
    ClientTable.client_id,
    ClientTable.first_name,
    AddressTable.account_id,
    AddressTable.street,
    AddressTable.city
FROM
    [clients] ClientTable
    INNER JOIN
    (
        SELECT
            [addresses].client_id,
            [addresses].account_id,
            [addresses].street,
            [addresses].city
        FROM [addresses]
        INNER JOIN [accounts] ON [addresses].client_id = [accounts].client_id
        WHERE [accounts].status <> 'cancelled'
    ) AddressTable ON ClientTable.client_id = AddressTable.client_id

您可以加​​入 clientsaddresses 表,并使用 not exists 驱逐“已取消”的帐户:

select cl.client_id, cl.first_name, ad.account_id, ad.street, ad.city
from clients cl
inner join addresses ad on ad.client_id = cl.client_id
where not exists (
    select 1 
    from accounts ac 
    where 
        ac.client_id = ad.client_id 
        and ac.account_id = ad.account_id
        and ac.status = 'cancelled'
)

另一种方法是在 accounts 上使用 join,正如您最初打算的那样:

select cl.client_id, cl.first_name, ad.account_id, ad.street, ad.city
from clients cl
inner join addresses ad on ad.client_id = cl.client_id
inner join accounts ac on ac.client_id = ad.client_id and ac.account_id = ad.account_id
where ac.status <> 'cancelled'

请注意,这两个查询做的事情并不完全相同;第二个查询需要一个状态为 non-cancelled 的帐户,而第一个只是禁止取消帐户(允许没有帐户的地址)。

Demo on DB Fiddle - 两个查询都产生:

client_id | first_name | account_id       | street        | city     
--------: | :--------- | :--------------- | :------------ | :--------
 10000000 | Samantha   | BBBBBBBBBBBBBBBB | 111 Orange St | Hong Kong
 10000001 | Andrew     | CCCCCCCCCCCCCCCC | 456 Grape St  | Amsterdam
 10000002 | Audrey     | DDDDDDDDDDDDDDDD | 789 Peach St  | Toronto