Eins von duplikaten Ergebnissen auswählen

Allex

Benutzer
Beiträge
9
Hallo,
ich habe 2 folgende Tabellen, also gleiche Name mit verschiedene Codes (code1 , code2). ich wollte die beide Tabellen mit "JOIN" irgendwie miteinander verbinden. Nach dem JOIN werde ich 4 Datensätze haben. Ich wollte aber aufgrund Name und code1 eins von code2 auswählen. Beispielsweise entweder (A, WP1, 01) oder (A, WP1, 02). bis hier hin kann man einfach mit RANK() Funktion eins davon auswählen. (wenn my_rank = 1)

**** Aber wichtig ist , wenn ich (A, WP1, 01) ausgewählt habe, darf nicht (A, WP2, 01) auswählen, weil code2 immer unterschiedlich sein soll. ****
D.h.
Entweder (A, WP1, 01) und (A, WP2, 02)
Oder (A, WP1, 02) und (A, WP2, 01)

Außerdem die beide Tabellen können mehrere Datensätze haben. zum Beispiel wenn Tabelle 1 und 2 drei Datensätze haben, soll JOIN Tabelle 9 Datensätze haben und soll genau mit oben genannten Erklärung 3 Datensätze mit verschiedenen Code2 haben.


Name code1
-----------------
A WP1
A WP2

Name code2 Name code1 code2 Name code1 code2 my_rank
----------------- ------------------ -----> ---------------------------- ---------> --------------------------------------
A WP1 A 01 A WP1 01 A WP1 01 1
A WP2 A 02 A WP1 02 A WP1 02 2
A WP2 01 A WP2 01 1
A WP2 02 A WP2 02 2




Name
Code1
A​
WP1​
A​
WP2​


Name
Code2
A​
01​
A​
02​


Name
Code1
Code2
A​
WP1​
01​
A​
WP1​
02​
A​
WP2​
01​
A​
WP2​
02​


Name
Code1
Code2
My_rank
A​
WP1​
01​
1​
A​
WP1​
02​
2​
A​
WP2​
01​
1​
A​
WP2​
02​
2​
 
Zuletzt bearbeitet:
Werbung:
Deine Erklärung ist schwer zu verstehen und die Datenkonstellation ist ebenfalls nicht so richtig eingegrenzt.
Sind die Datensätze in den Tabellen eindeutig? Sind einzelne Spalten eindeutig?

Es wäre auch hilfreich, Tabellen beim Namen zu nennen, dann kann man sich darauf beziehen.

Was Du beschreibst mit rank Verfahren, klingt nach einem Kreuzprodukt. Aber alles mit allem zu kombinieren und dann wieder zu filtern ist mühsam.
Ich habe eine künstliche Spalte mit fortlaufenden Werten als hartes Join Kriterium produziert.
2 Varianten, die auch noch einfacher sein könnten, je nach Datenkonstellation.
Code:
select e.name, e.code1, z.code2
  from (select row_number() over(order by code1) rn, name, code1
          from eins) e
  join (select row_number() over(order by code2) rn, name, code2
          from zwei)) z
    on e.rn = z.rn
   and e.name = z.name

select e.name, e.code1, z.code2
  from (select row_number() over(order by code1) rn, name, code1
          from (Select distinct * from eins)) e
  join (select row_number() over(order by code2) rn, code2
          from (Select distinct code2 from zwei)) z
    on e.rn = z.rn
 
Deine Erklärung ist schwer zu verstehen und die Datenkonstellation ist ebenfalls nicht so richtig eingegrenzt.
Sind die Datensätze in den Tabellen eindeutig? Sind einzelne Spalten eindeutig?

Es wäre auch hilfreich, Tabellen beim Namen zu nennen, dann kann man sich darauf beziehen.

Was Du beschreibst mit rank Verfahren, klingt nach einem Kreuzprodukt. Aber alles mit allem zu kombinieren und dann wieder zu filtern ist mühsam.
Ich habe eine künstliche Spalte mit fortlaufenden Werten als hartes Join Kriterium produziert.
2 Varianten, die auch noch einfacher sein könnten, je nach Datenkonstellation.
Code:
select e.name, e.code1, z.code2
  from (select row_number() over(order by code1) rn, name, code1
          from eins) e
  join (select row_number() over(order by code2) rn, name, code2
          from zwei)) z
    on e.rn = z.rn
   and e.name = z.name

select e.name, e.code1, z.code2
  from (select row_number() over(order by code1) rn, name, code1
          from (Select distinct * from eins)) e
  join (select row_number() over(order by code2) rn, code2
          from (Select distinct code2 from zwei)) z
    on e.rn = z.rn

Erstens, lieben Dank für deine Antwort.
Dann hast du ja recht. Es sieht so aus, dass ich nicht deutlich erklären konnte. Also denk mal daran, dass wir nur eine Tabelle haben, die nach dem JOIN zwischen Tabelle eins und zwei gebildet wurde aber habe ich kein Zugang auf den Tabelle eins und zwei.
Beziehungsweise habe ich derzeit nur diese Tabelle :

NameCode1Code2
AWP101
AWP102
AWP201
AWP202

jetzt wollte ich davon, solche Ergebnisse (aufgrund der oben genannten Erklärungen) bekommen.
D.h.
Entweder (A, WP1, 01) und (A, WP2, 02)
Oder (A, WP1, 02) und (A, WP2, 01)
 
Window functions sind die Lösung:

Code:
select x.name, x.code1, x.code2
from (
   select name, code1, code2, row_number() over (partition by name, code1 order by code2) as rn
   from ( .... die orginale Abfrage ...) basis
) x
where x.rn = 1
order by x.name, x.code1;

Oder mit einer common table expression:
Code:
with basis (
..   die orginale Abfrage ...
)
select x.name, x.code1, x.code2
from (
   select name, code1, code2, row_number() over (partition by name, code1 order by code2) as rn
   from basis
) x
where x.rn = 1
order by x.name, x.code1;
 
Zuerst hast Du zwei Tabellen, jetzt nur eine?
weil code2 immer unterschiedlich sein soll.
Diese Anforderung ist ziemlich deutlich.
Wie erzeugst Du Eindeutigkeit in SQL?
Select distinct ..
oder
Select .. group by..

Wie bekommst Du einen Join? Durch Join Kriterien.
Wenn es keine gibt, muss man passende finden.
Wenn ich 2 Tabellen vereinige und dabei große Mengen erzeuge, die ich anschließend wieder filtere, ist das auch suboptimal.

Was ist mit Deinen Werten (Code1 und code2), beliebig? Mehrfach?
Was ist mit 4 und 9 Datensätzen versus 2 und 3 Ausgangsdatensätzen? Sprechen wir über eine Tabelle oder über Potenzen aus Permutationen von 2 Tabellen?

Also schreib bitte ein definiertes Setting. Ist Daten, soll Daten, Datenbeschaffenheit.
Gibt es innere Zusammenhänge zwischen den Codes oder nicht?
Sind die Zusammenhänge unbekannt und werden gesucht?
Sind die Daten in irgendeiner Form geordnet? Sollen sie anschließend geordnet sein?
Gibt außer der geforderten Eindeutigkeit von code2 am Ende andere Kriterien?

Was auch hilfreich zum Verständnis ist: wie sind diese Daten entstanden? Ein Unfall? Ein stochaistisches Problem aus der Uni? Ein knappes Beispiel ist immer gut, sogar gefordert und gern gesehen im Forum. Aber ein Kontext, Intention ist manchmal Gold wert.
 
Window functions sind die Lösung:

Code:
select x.name, x.code1, x.code2
from (
   select name, code1, code2, row_number() over (partition by name, code1 order by code2) as rn
   from ( .... die orginale Abfrage ...) basis
) x
where x.rn = 1
order by x.name, x.code1;

Oder mit einer common table expression:
Code:
with basis (
..   die orginale Abfrage ...
)
select x.name, x.code1, x.code2
from (
   select name, code1, code2, row_number() over (partition by name, code1 order by code2) as rn
   from basis
) x
where x.rn = 1
order by x.name, x.code1;

leider funktioniert deine Lösung nicht und kriegen wir duplikate Code2 :

Name​
Code1​
Code2​
A​
WP1​
01​
A​
WP2​
01
A​
WP3​
01
 
Zuerst hast Du zwei Tabellen, jetzt nur eine?

Diese Anforderung ist ziemlich deutlich.
Wie erzeugst Du Eindeutigkeit in SQL?
Select distinct ..
oder
Select .. group by..

Wie bekommst Du einen Join? Durch Join Kriterien.
Wenn es keine gibt, muss man passende finden.
Wenn ich 2 Tabellen vereinige und dabei große Mengen erzeuge, die ich anschließend wieder filtere, ist das auch suboptimal.

Was ist mit Deinen Werten (Code1 und code2), beliebig? Mehrfach?
Was ist mit 4 und 9 Datensätzen versus 2 und 3 Ausgangsdatensätzen? Sprechen wir über eine Tabelle oder über Potenzen aus Permutationen von 2 Tabellen?

Also schreib bitte ein definiertes Setting. Ist Daten, soll Daten, Datenbeschaffenheit.
Gibt es innere Zusammenhänge zwischen den Codes oder nicht?
Sind die Zusammenhänge unbekannt und werden gesucht?
Sind die Daten in irgendeiner Form geordnet? Sollen sie anschließend geordnet sein?
Gibt außer der geforderten Eindeutigkeit von code2 am Ende andere Kriterien?

Was auch hilfreich zum Verständnis ist: wie sind diese Daten entstanden? Ein Unfall? Ein stochaistisches Problem aus der Uni? Ein knappes Beispiel ist immer gut, sogar gefordert und gern gesehen im Forum. Aber ein Kontext, Intention ist manchmal Gold wert.
Ich habe nur ein Skript bekommen und das Ergebnis ist genauso wie Tabelle, die ich erwhnt habe. bzw, habe ich derzeit ein Skript, das ich nicht ändern darf und soll aber davon richtige Datensätze (wie ich schon mal oben erklärt habe) raus nehmen.
mehr habe ich auch selbst keine Ahnung zur Erklärung

Name​
Code1​
Code2​
A
WP1
01
A​
WP1​
02​
A​
WP1​
03​
A​
WP2​
01​
A​
WP2​
02​
A
WP2
03
A​
WP3​
01​
A
WP3
02
A​
WP3​
03​


Falls ich 2 Tabelle hätte, wäre dein erstes Skript ja super funktioniert. aber habe ich leider ein Skript mit oben genannten Ergebnisse.
 
Naja, notfalls könntest Du ja auch wieder 2 Tabellen draus machen.
Aber wenn es so ist wie es ist, und die Daten liegen bereits so vor, nimm die Lösung von @castorp.
 
Werbung:
Ich danke euch beiden für eure Hilfe.

ich habe aufgrund eure Erklärungen unten genannten Skript laufen lassen und es funktioniert richtig.

With eins AS
(
select row_number() over(order by code1) rn, name, code1
from eins_test
)
,
zwei AS
(
select row_number() over(order by code2) rn, name, code2
from zwei_test
)

SELECT eins.name, eins.code1, zwei.code2
FROM eins,zwei
WHERE eins.name = zwei.name
AND eins.rn = zwei.rn
;
 
Zurück
Oben