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

时间:2015-07-21 18:03:56

标签: mysql sql where-clause

我有一个客户表和一个单独的表来存储客户的地址。它们通常在地址表中至少有两个连接的记录,如果不是更多的话。当我想要一个邮件列表时,我想要客户的帐单地址,该地址由地址表中的“类型”列标记。不幸的是,并非每个客户都有一个标记为“结算”的地址。我怎样才能写一个声明,说选择标记为开票的地址,除非没有,在这种情况下选择另一个。我不想只使用'或',因为我只想选择一条记录。

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

  

客户:
  ID

     

地址:
  ID
  客户ID
  类型(运费,账单,'等)

这里有一些sql不是我想要的(lol): 从address.custid = Customer.id中的Customer inner join Address中选择*,其中Address.type ='billing'

!!迟到!!
Kevin提供了coalesce解决方案,我非常喜欢它,但它只适用于地址表中的单个列。我需要表格中的所有字段/列才能形成可用的地址。

我一直在尝试这样做(为简单起见,这里仅使用两个字段):
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通过始终返回非null来打破合并 我还尝试在每个字段上独立进行合并:
coalesce(a1.address, a2.address), coalesce(a1.address2, a2.address2), etc
但这会产生“混合”来自3个不同记录的地址的效果,例如地址2(对于公寓号或其他)对于行是空的,那么它将在那里插入不同记录的地址2。

有人知道如何阻止concat_ws返回非null,即使字段内部为null吗?

4 个答案:

答案 0 :(得分:2)

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')

这是一种方法。

答案 1 :(得分:1)

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

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'

答案 2 :(得分:0)

没有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'

答案 3 :(得分:0)

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'
)

如果你需要它更通用一点,那么你可能会觉得这个“黑客”很有用:

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
)