带有Member和Member_phone表的Oracle SQL Query连接

时间:2011-09-23 17:43:40

标签: sql oracle

MEMBER表,主键MEMBER_ID和MEMBER_PHONE表,MEMBER_ID为外键,PHONE_IND为列之一,值为'S'(辅助电话)或'P'(主电话)以及电话号码详细信息。 'S'是我们的关键价值。

如果'S'存在,我需要oracle查询用电话获取会员信息,如果不是'P'电话号码。

在MEMBER_PHONE表中,每个成员都有两个可能的行'S'和'P',如果不是至少'P'作为一行。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,会员可以有一个可选的'S'电话号码,并且总是有一个'P'电话号码。如果存在“S”号码,则需要返回成员信息以及该号码。如果没有,你想要后退并返回会员信息和'P'号码,对吗?

select
  *
from
  MEMBER m
  inner join MEMBER_PHONE p on p.MEMBER_ID = m.MEMBER_ID
where
  p.PHONE_IND = 'S' or
  ( p.PHONE_IND = 'P' and
    not exists (
      select * 
      from MEMBER_PHONE p 
      where p.PHONE_IND = 'S' and p.MEMBER_ID = m.MEMBER_ID)
  )

[edit]这是一种有趣的查询。这是一个完全不同的方法:

select
  m.*,
  pp.*  
from 
  MEMBER m
  left join MEMBER_PHONE ps 
    on ps.MEMBER_ID = m.MEMBER_ID 
    and ps.PHONE_IND = 'S'
  inner join MEMBER_PHONE pp 
    on pp.MEMBER_ID = m.MEMBER_ID 
    and pp.PHONE_IND = nvl(ps.PHONE_IND, 'P')

检查自己哪个工作/表现最佳。

[编辑2]通过评论再次提出这个问题,所以我决定添加另一个。如您所见,很难不解决这个问题。 ; - )

select
  *
from
  (select
    m.*,
    p.*,
    dense_rank() over (
      partition by m.MEMBER_ID 
      order by decode(p.PHONE_IND, 'S', 1, 2)) as RANK
  from 
    MEMBER m
    inner join MEMBER_PHONE p on pp.MEMBER_ID = m.MEMBER_ID )
where
  RANK = 1

答案 1 :(得分:0)

select m.*
  from MEMBER m
 where exists ( select 1
                  from MEMBER_PHONE mp
                 where mp.member_id = m.member_id
                   and mp.phone_ind = 'S' ); 

修改

我想知道我明白了......

select m.*
     , mp.*
  from member m left outer join
      member_phone mp on m.member_id  = mp.member_id
 where (mp.phone_ind = 'S'
    or ( mp.phone_ind = 'P'
   and not exists( select 1
                     from member_phone mp1
                    where mp1.member_id = mp.member_id
                      and mp1.phone_ind = 'S' )))