2017-03-03 4 views
1

Ich habe eine verwirrende Logik. Ich habe eine Tabelle person_details, es hat einen eindeutigen Primärschlüssel id und Fremdschlüssel persid. Ein anderer Fremdschlüssel ist common_id. Die common_id basiert auf 1 und 2. Wenn 1, bedeutet das asset. Wenn 2, dann bedeutet das liability.Beitreten derselben Tabelle gibt einige Spalten wiederholen

Die person_details Tabelle:

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

Ich möchte die Aktiv- und Passiv Details erhalten trennen und zurück eine einzelne Abfrage beitreten. Wenn ich eine einfache Abfrage versuche, gibt es einen wiederholten Haftungseintrag.

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 

Jetzt gibt es:

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

ich zurückkehren wollen

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

Bitte erläutern Sie Ihre erwartete Ausgabe – GurV

Antwort

0

Es scheint, dass Sie nur die erste Zeile aus einer Gruppe von Vermögenswerten mit der ersten Reihe anschließen möchten, von eine Gruppe von Verbindlichkeiten. Wenn dies der Fall ist, wäre eine Option, ein CTE zu verwenden und jedem Datensatz der zwei Gruppen eine Zeilennummer zuzuweisen. Verwenden Sie dies dann in der Join-Bedingung, um sicherzustellen, dass nur der erste Datensatz für Vermögenswerte/Verbindlichkeiten übereinstimmt.

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; 

Ausgang:

enter image description here

0

Zu einem gewissen Grad ist dies scheint wie ein Modellierungsproblem: person_details fühlt sich an wie es sollte zwei Tabellen sein. Diese Lösung verwendet die Unterabfrage-Factory, um die Tabelle in zwei Ergebnismengen aufzuteilen und verwendet einen linken äußeren Join. Dies verhindert eine Duplizierung von Haftungsansprüchen.

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 
/

Diese Lösung löst das Problem für die Daten, die Sie gebucht haben. Wo dies nicht funktioniert, ist, wenn es mehr Haftungsnachweise als Asset-Datensätze gibt. In diesem Fall benötigen Sie einen vollständigen äußeren Join.

+0

es gibt Liability_details null für alle Zeilen zurück –

Verwandte Themen