2011-02-02 117 views
1

让我们说我有一个名为“Company”的表,其中有一个CompanyID的密钥 还有另一个名为“CompanyAddress”的相关表,它具有CompanyID外键,因此可以轻松建立联接。有条件的DB2 SQL查询

该公司地址表中可以有一个给定公司的多个地址,说的AddressType = 1,或地址类型= 2

的加盟等,以获得该领域是微不足道的,但是我希望有一个条件,我在那里查询地址,并使用地址类型= 1,如果它的存在,如果没有,用的AddressType = 2

目前,我想这样做工会和删除重复的,但必须有一个更好的办法

回答

2

它实际上是非常容易做到这一点(如果您正在使用DB2 Linux版/ UNIX/Windows)通过使用OLAP函数。我已经猜到了公司地址表中的一些列名称,但“魔术”在rank()函数中:

with preferredAddresses as (
    select 
     companyID, 
     address, 
     addresstype, 
     rank() over (partition by companyID order by addresstype) as rank 
    from 
     companyAddress 
) 
select * 
from 
    company C, 
    inner join preferredAddresses A 
     on c.companyID = A.companyID 
where 
    A.rank = 1; 
+0

+1这将与DB2 for IBM i V5R4 – 2011-02-03 16:19:33

2

一个联盟而不存在测试似乎是这样的方式去

select * 
from company C 
inner join CompanyAddress A on A.companyID = C.companyID 
where A.AddressType = 1 
union all 
select * 
from company C 
LEFT join CompanyAddress A on A.companyID = C.companyID 
    and A.AddressType = 2 
    and not exists (
    select * 
    from CompanyAddress B 
    where B.companyID = C.companyID 
     and B.AddressType = 1) 

第二部分使用左连接,以便既没有地址类型1也没有2的公司仍将显示。
要么是这样,要么使用左连接来AddressType = 2,只有当第一个连接(type = 1)失败时才会触发。

select C.*, 
    coalesce(A.addressType, B.addressType) addressType, 
    coalesce(A.streetname, B.streetname) streetname 
from company C 
left join CompanyAddress A on A.companyID = C.companyID and A.AddressType = 1 
left join CompanyAddress B on A.companyID is null 
    AND B.companyID = C.companyID and B.AddressType = 2 

正如你所看到的,这是很难,因为从地址每一列都必须经过​​3210 A和B之间