2016-07-28 6 views
1

Ich habe einige Probleme versuchen, herauszufinden, wie man eine SQL-Anweisung, die die gleiche Menge an Datensätzen in der linken Tabelle gefunden zurückgibt.Join das wird die gleiche Anzahl von Datensätzen auf der linken Seite Tabelle

Zum Beispiel haben wir zwei Tabellen, Transaktionen und Partner. Aufgrund der ursprünglichen Gestaltung der Tabellen gibt es keine Möglichkeit, ein exakt übereinstimmendes Paar zu erhalten. IE. Eine Transaktion könnte viele Partner haben, auf die sie sich bezieht.

Was ich suche, ist, alle Transaktionen mit einer Partner-ID anzuzeigen. Wenn eine Transaktion mehr als eine übereinstimmende Partner-ID hat, muss ich das erste Vorkommen des Spiels übernehmen und den Rest wegwerfen. Wenn eine Transaktion keine übereinstimmende Partner-ID hat, muss ich sie trotzdem anzeigen, aber mit einem leeren oder Null-Wert für die Partner-ID.

Transaktionstabelle

Transaction ID | ID 1 | ID 2 
-------------- +---------+---------- 
T1    | A  | 1 
T2    | C  | 3 
T3    | B  | 1 
T4    | D  | 4 
T5    | A  | 2 

Partner Tabelle

Transaction ID | ID 1 | ID 2 
---------------+---------+---------- 
P1    | A  | 1 
P2    | B  | 2 
P3    | C  | 3 
P4    | C  | 3 
P5    | D  | 4 

gewünschten Ergebnisse

Transaction ID| ID 1 | ID 2  | Partner ID 
--------------+---------+----------+----------- 
T1   | A  | 1  | P1 
T2   | C  | 3  | P3 
T3   | B  | 1  | Null 
T4   | D  | 4  | P5 
T5   | A  | 2  | Null 

Ich fühle mich wie eine Form der äußeren müssen kommen sicher sind keine Transaktionen machen nicht abgefragt, aber ich kann nicht entschlüsseln, wie man sicherstellt, dass keine doppelten Transaktionen angezeigt werden.

Dank

Antwort

1

SQL-Tabellen haben kein Konzept des "ersten" Datensatzes, ohne irgendeine Spalte, um die Reihenfolge anzugeben. Aber die Grundidee, was Sie wollen verwendet left join und row_number():

select t.*, p.partnerid 
from transaction t left join 
    (select p.*, 
      row_number() over (partition by id1, id2 order by partnerid) as seqnum 
     from partner p 
    ) p 
    on t.id1 = p.id1 and t.id2 = p.id2 and p.seqnum = 1; 

Diese Version „ersten“ Takes „niedrigsten Wert von Partner-ID“ bedeuten.

+0

Vielen Dank, das funktioniert perfekt. – Soul3lade

0

Sie können eine outer join mit row_number verwenden:

select * 
from (
    select t1.transactionid, t1.id1, t1.id2, t2.transactionid as partnerid, 
      row_number() over (partition by t1.transactionid order by t2.transactionid) rn 
    from Transaction t1 
     left join Partner t2 on t1.id1 = t2.id1 and t1.id2 = t2.id2 
) t 
where rn = 1 

Dies wählt alle Datensätze aus transaction Tabelle und dann nur 1 von der partner Tabelle, wenn es vorhanden ist.

0

Ich bin nicht sicher, wie Sie wissen, dass Sie nicht möchten, P4 mit T2 sowie P3 eine Partnerschaft, aber ich fand das für mich gearbeitet, es ist die lowest ID vorausgesetzt:

select t1.transactionid, t1.id1, t1.id2, min(t2.transactionid) as partnerid 
from Transaction t1, Partner t2 where t1.id1 = t2.id1(+) and t1.id2 = t2.id2(+) 
group by t1.transactionid, t1.id1, t1.id2 
order by t1.transactionid, t1.id1, t1.id2 
+0

Ich habe die Tabellen für die Frage stark vereinfacht, aber im Grunde hätte jeder Partner einen Partnernamen. In der Tabelle könnten 3 Partner mit unterschiedlichen Transaktionen eingerichtet sein, aber sie würden jeweils den gleichen Namen haben. Alles, was ich anzeigen muss, ist der Name des Partners, es spielt also keine Rolle, dass eine Transaktion zu mehreren Partnern passt, da die Spalte, nach der ich spreche, zwischen diesen Partnern gleich ist. – Soul3lade

Verwandte Themen