2014-11-09 80 views
1

我有一個包含一些數據的兩個表的連接和後組:顯示在表中的記錄按特定的列

表1:ABC

||entity_id| entity_title| cust_code| cust_acc_no  || 
---------------------------------------------------------- 
|| AB101Z | IND  | 101Z | 1234   ||  
|| AB101Z | PAK  | 101Z | 1357   ||  
|| CD101Y | IND  | 101Y | 2468   || 
|| EF101X | IND  | 101X | 3579   ||  
|| JK201N | LKO  | 201N | 5678   || 

表2:高清

||entity_title| in_count| out_quant|| 
--------------------------------------------- 
|| IND  | 10 |  7 ||  
|| LKO  | 7 |  7 ||  
|| PAK  | 5 |  2 || 

加入的表格:abcdef

||entity_id| entity_title| cust_code ||  
-------------------------------------------------- 
|| AB101Z | INDPAK |  101Z || 
|| CD101Y | INDPAK |  101Y ||   
|| EF101X | INDPAK |  101X || 

我想加入表ABC高清這將是表結果ABCDEF

加入這兩個表和記錄時,將按entity_title分組。加入條件將如此in_count!=out_count。例如,在這種情況下,LKOentity_title不會是結果表的一部分。

我需要用符合條件的entity_title記錄替換表示匹配記錄的第三條記錄,例如,INDPAK是所有記錄的替代品,無論這些記錄是否適用於IND和PAK兩者或其中之一。

我試圖想出一個解決方案,但無法形成一個單一的查詢。提前感謝任何解決方案建議。

回答

0

該解決方案避免了硬編碼。它包括三個步驟:

  • 第一子查詢標識爲具有不同計數ENTITY_TITLEs常見(ENTITY_ID,CUST_CODE)組合。

  • 第二個子查詢標識擁有這些組合的ENTITY_TITLE併爲它們派生一個複合ENTITY_TITLE。 (它使用LISTAGG,它是一個11gR2的東西,但是在早期版本的數據庫中有字符串連接的解決方法)。

  • 外部查詢生成所需的輸出,將複合ENTITY_TITLE替換爲原始的ENTITY_TITLE。

這是整件事情。我承認我不喜歡它依賴DISTINCT子句來獲得所需的輸出,但是加入規則會產生不需要的重複項。

with prs as 
    (select abc.entity_id 
      , abc.cust_code 
     from abc 
      join def 
      on abc.entity_title = def.entity_title 
     where def.in_count != def.out_quant 
     group by abc.entity_id, abc.cust_code having count(*) > 1 
    ) 
    , ent as 
    (select distinct abc.entity_title 
       , listagg(abc.entity_title) 
        within group (order by abc.entity_title) 
        over (partition by prs.entity_id, prs.cust_code) as cmp_entity_title 
     from abc 
      join prs 
    on abc.entity_id = prs.entity_id 
    and abc.cust_code = prs.cust_code 
    ) 
select distinct abc.entity_id 
     , ent.cmp_entity_title 
     , abc.cust_code 
from ent 
    join abc 
    on abc.entity_title = ent.entity_title 
order by abc.entity_id 
     , abc.cust_code 
/

請注意,輸出對數據的初始條件強烈依賴。如果您查看我的inevitable SQL Fiddle,您會看到我已將其他行添加到設置中。

第一註釋掉ABC紀錄......

/* insert into abc values ('AB101Z','BAN','101Z',  5151  ); */ 

..創建一個匹配的三倍,BANINDPAK,它取代BAN,IND或PAK的所有地方。這是您的規則的合乎邏輯的結果,我認爲您會期望這一結果。

其他註釋掉ABC紀錄......

/* insert into abc values ('JK101X','TIB','101K',  3434  ); */ 

...創建第二配對,PAKTIB,它的存在產生了PAK實體的記錄多個結果。這也是你的規則的合乎邏輯的結果,但也許是預期不太理想的結果。

+0

感謝您的回覆,但不希望輸出。查詢不包括輸出中的下列行: ** CD101Y | \t INDPAK | \t 101Y ** INDPAK將替代所有記錄,無論這些記錄是針對IND和PAK還是針對這兩種記錄中的任何一種 – 2014-11-09 19:03:28

0
select e.entity_id, b.entity_title,e.cust_code 
from abc e inner join def b 
on  e.entity_title=b.entity_title 
where b.in_count!=b.out_count 
group by b.entity_title 
+0

這不會給出預期的結果。 – 2014-11-09 08:30:14

0

here的東西,可以幫助你:

select * from 
(
    select t1.entity_id, case when t1.entity_title in('IND','PAK') then 'INDPAK' else t1.entity_title end as entity_title, t1.cust_code 
    from abc t1 join def t2 
    on  t1.entity_title = t2.entity_title 
    where t2.in_count <> t2.out_count 

) t 
group by t.entity_id, t.entity_title, t.cust_code 
+0

這隻適用於對INDPAK摘要進行硬編碼,但看起來不合乎要求。雖然因爲這個問題是模糊的,所以它可能是正確的答案:) – APC 2014-11-09 15:01:46

+0

道歉歧義.. :( @ user2315555感謝您的reply.Fiddle顯示所需的輸出,但參數已被硬編碼query.How我將這個查詢格式化以去除硬編碼 – 2014-11-09 19:02:00

+0

你的意思是你有更多'entity_title'類似於IND/PAK,並且你想連接它們所有的?例如在abc'AB101Z AUS 101Z 1214'中有一個條目,那麼你想要得到的結果行爲'AB101Z AUSINDPAK 101Z'。 – 2014-11-10 05:30:45