MySQL Join 只从一系列条件中选择了一个条件

MySQL Join chose only 1 condition from a series of conditions

我有一个客户 table 和一个单独的 table 存储客户地址。他们通常在地址 table 中至少有两个连接记录,如果不是更多的话。当我想要一个邮寄列表时,我想要客户的账单地址,在地址 table 中用 'type' 列标记。不幸的是,并非每个客户都有一个标记为 'billing' 的地址。我怎样才能写一份声明,说要选择标记为账单的地址,除非没有,在这种情况下选择另一个。我不想只使用 'or' 因为我只想选择一条记录。

为简单起见,tables 可能如下所示:

Customer:
id

Address:
id
custid
type (shipping, billing, '', etc)

还有一些 sql 不是我想要的(笑): Select * 来自 address.custid = Customer.id 上的客户内部加入地址,其中 Address.type = 'billing'

!!后期添加!!
Kevin 提供了我非常喜欢的合并解决方案,但它只适用于地址 table 中的单个列。我需要 table 中的所有 fields/columns 来形成可用地址。

我一直在尝试这样做(为了简单起见,这里只使用了两个字段):
select coalesce(concat_ws(',',a1.address, a1.city), concat_ws(',',a2.address, a2.city), concat_ws(',',a3.address, a3.city)) from customer c ...
但是,concat_ws 总是返回非空值,从而破坏了合并。
我还尝试在每个字段上独立进行合并:
coalesce(a1.address, a2.address), coalesce(a1.address2, a2.address2), etc
但这具有来自 3 个不同记录的 'mixing up' 地址的效果,如果例如 address2(用于公寓号或其他)对于一行为 null,则它将在其中插入不同记录的 address2。

有谁知道如何防止 concat_ws 返回非空值,即使字段内部为空值也是如此?

select c.id, a.id
from customer c join address a on a.custid = c.id
where a.type = 'Billing'
union
select c.id, a.id
from customer c join address a on a.custid = c.id
where a.type <> 'Billing' 
and c.id not in (select custid from address a where a.type = 'Billing')

这是一种方法。

如果没有 OR 子句,很难做到这一点。假设您要查找地址 ID:

SELECT
Address.id
FROM Address LEFT JOIN Customer ON Customer.id = Address.custid
WHERE Address.id EXIST (
    SELECT
    Address.id
    FROM Address LEFT JOIN Customer ON Customer.id = Address.custid
    WHERE Address.type LIKE 'shipping'
) OR Address.type = 'billing'

这将为您提供帐单地址(如果存在),否则送货地址:

select ifnull(a1.address, a2.address) from customer c
left join address a1 on c.id = a1.custid and a1.type = 'billing'
left join address a2 on c.id = a2.custid and a2.type = 'shipping'

如果您想检查其他类型,您可以添加连接并使用 coalesce 而不是 ifnull,如下所示:

select coalesce(a1.address, a2.address, a3.address) from customer c
left join address a1 on c.id = a1.custid and a1.type = 'billing'
left join address a2 on c.id = a2.custid and a2.type = 'shipping'
left join address a3 on c.id = a3.custid and a3.type = 'X'
select ...
from customer c join address a on a.custid = c.id
where a.type = 'Shipping'
union all
select ...
from customer c join address a on a.custid = c.id
where a.type = 'Billing' and not exists (
    select 1 from address a2
    where a2.custid = a.custid and a2.type = 'Shipping'
)

如果您需要它更通用一点,那么您可能会发现这个 "hack" 很有用:

select * from address
where id in (
    select
        min(case type
            when 'Shipping' then 100000000
            when 'Billing'  then 200000000
            when ...        then 300000000
            else 900000000
        end + a.id) % 100000000 /* not sure of MySQL for modulo operation */
    from address a
    group by custid
)