2017-03-03 45 views
1

我有一個令人困惑的邏輯。我有一個表person_details,它有一個唯一的主鍵id和外鍵persid。另一個外鍵是common_idcommon_id基於1和2.如果是1,表示asset。如果是2,則表示liability加入同一個表返回一些列重複

person_details表:

| id | details   |persid | common_id | 
|_____|__________________|_______|____________| 
    200 asset details  30   1 
    201 asset details2 30   1 
    203 liability detail 30   2 

我想要得到的資產和負債的細節分離和返回一個連接查詢。當我嘗試一個簡單的查詢時,它會返回重複輸入責任。

select a.details assetdet, 
     b.details liabdetails, 
     a.common_id assetid, 
     b.common_id liabId 
from person_details a 
join person_details b 
    on a.persid = b.persid 
where a.common_id = 1 and 
     b.common_id = 2 and 
     a.persid = 30 

現在返回:

| assetdet  | liabdetails | assetid | liabId | 
|_______________|_________________|____________|__________| 
asset details liability detail  1   2 
asset details2 liability detail  1   2 

我想回到

| assetdet  | liabdetails | assetid | liabId | 
|_______________|_________________|____________|__________| 
asset details liability detail  1   2 
asset details2 null    1   null 
+1

請解釋您的預期輸出 – GurV

回答

0

看來,你只是想加入從一組資產的第一行與第一排一組負債。如果是這樣,那麼一種選擇是使用CTE併爲兩組的每個記錄分配一個行號。然後在連接條件中使用它來確保只有資產/負債的第一條記錄匹配。

WITH cte AS (
    SELECT id, details, persid, common_id, 
      ROW_NUMBER() OVER (PARTITION BY common_id ORDER BY id) rn 
    FROM person_details 
) 

SELECT a.details assetdet, 
     b.details liabdetails, 
     a.common_id assetid, 
     b.common_id liabId 
FROM cte a 
LEFT JOIN cte b 
    ON a.persid = b.persid AND 
     a.rn = 1 AND 
     b.rn = 1 AND 
     b.common_id = 2 AND 
     a.persid = 30 
WHERE a.common_id = 1; 

輸出:

enter image description here

0

在某種程度上,這是似乎是一個建模問題:person_details感覺它應該是兩個表。無論如何,此解決方案使用子查詢工廠將表拆分爲兩個結果集並使用左外部聯接。這將防止重複責任記錄。

with asst as (
    select id 
      , details 
      , persid 
      , row_number() over (order by id) rn 
    from person_details 
    where common_id = 1 
) 
, liab as (
    select id 
      , details 
      , persid 
      , row_number() over (order by id) rn 
    from person_details 
    where common_id = 2 
) 
select asst.details as asset_details 
     , liab.details as liability_details 
     , asst.common_id as asset_id 
     , liab.common_id as liability_id 
from asst 
left outer join liab 
    on asst.persid = liab.persid 
    and asst.rn = liab.rn 
where asst.persid = 30 
/

該解決方案解決了您發佈的數據的問題。如果這不起作用,那麼當有更多的責任記錄比資產記錄。在這種情況下,你需要一個完整的外連接。

+0

它返回所有行的liability_details null –