2017-02-01 18 views
2

我正在進行查詢以獲取學生聯繫人的郵件地址,並且在那裏我有點卡住了。我已經設法得到所有學生和他們的聯繫人的名單,但現在當我嘗試將聯繫人加入他們的地址時,我不確定如何得到正確的地址。基於地址類型的Oracle條件選擇

在地址表中可以容納多種地址(家庭,郵件,商務,皮卡,丟棄),基本上我只需要爲每個聯繫人帶回一個地址。

通常情況下,這將是家庭地址,除非有一個郵寄地址

所以我的問題是我如何寫某種類型的條件語句中只得到條目WHERE ADDRESS_TYPE_NAME =「家」,除非還有一個條目WHERE ADDRESS_TYPE_NAME ='郵寄'相同的PERSON_ID?

感謝

+2

請添加您的示例輸入和預期輸出 – GurV

+0

學生可以有多個家庭住址(或多個郵寄地址)嗎?如果是這樣,應該選擇什麼?另外,保證每個學生至少有一個家或郵寄地址?如果不是,該爲學生顯示什麼? – mathguy

回答

0
with CTE as 
(
select Person_id, 
     Address_Type_Name, 
     Address_Info -- replace with your real column names 
from Address_Table 
where Address_Type_Name in ('Home','Mailing') 
) 
select Person_id, Address_info 
from CTE a1 
where Address_Type_Name = 'Home' 
and not exists (select 1 
       from CTE a2 
       where a2.Address_Type_Name = 'Mailing' 
       and a2.Person_id = a1.Person_id) 
union 
select Person_id, Address_info 
from CTE a1 
where Address_Type_Name = 'Mailing' 
0

您可以優先地址類型,並用

select Person_id, 
    case min(case Address_Type_Name 
      when 'Mailing' then 1 
      when 'Home' then 2 
      -- more 
      end) 
     when 1 then 'Mailing' 
     when 2 then 'Home' 
     -- more 
    end Best_Address_Type_Name 
from Address_Table 
group by Person_id; 

獲得最高優先級類型需要

+0

爲什麼加入而不是使用已經擁有的group_by?爲地址本身添加一列(您可能需要使用'keep(dense_rank first/last order by <與您已有的相同的東西>)')。 – mathguy

+0

@mathguy我同意它可能是OP想要的結果。或者它可能是更復雜的查詢的一部分,不知道。 – Serg

0

這裏的結果。然後加入到你的數據是做到這一點的一種方式,使用row_number()分析函數並且不需要任何連接,顯式或隱式。它還處理各種特殊情況:既沒有郵寄地址也沒有家庭地址(但仍然需要在輸出中顯示)的學生,以及具有兩個郵寄地址的另一名學生(在這種情況下,隨機選擇一個);如果有喜歡一個到另一個,查詢可以很容易地適應,以適應)。

with 
    students (id, name, address_type, address) as (
     select 11, 'Andy', 'home' , '123 X street' from dual union all 
     select 11, 'Andy', 'office' , 'somewhere else' from dual union all 
     select 15, 'Eva' , 'mailing', 'post office' from dual union all 
     select 18, 'Jim' , 'office' , '1 building'  from dual union all 
     select 30, 'Mary', 'mailing', 'mail addr 1' from dual union all 
     select 30, 'Mary', 'office' , '1 building'  from dual union all 
     select 30, 'Mary', 'home' , 'her home'  from dual union all 
     select 30, 'Mary', 'mailing', 'mail addr 2' from dual 
    ) 
-- End of test data (not needed for the SQL query - reference your actual table) 
select id, name, address_type, 
     case when address_type is not null then address end as address 
from (
     select id, name, 
        case when address_type in ('home', 'mailing') 
         then address_type end as address_type, 
        address, 
        row_number() over (partition by id 
          order by case address_type when 'mailing' then 0 
                when 'home' then 1 end) as rn 
      from students 
     ) 
where rn = 1 
; 

ID NAME ADDRESS_TYPE ADDRESS 
--- ---- ------------ -------------- 
11 Andy home   123 X street 
15 Eva mailing  post office 
18 Jim 
30 Mary mailing  mail addr 1 

4 rows selected.