Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

left join eingrenzen auf bestimmte Zeilen abhängig von Werten einer Spalte

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von abenteurer, 11 März 2013.

  1. abenteurer

    abenteurer Benutzer

    Hallo,
    ich habe folgendes Problem:

    ich brauchen einen left join zwischen zwei Tabellen. Die beiden haben eine 1:n Beziehung. Nun will sowas wie eine "Prioritätenliste" für Tabelle 2 falls mehrere Einträge vorhanden sind.

    Also etwa: Falls einer der Einträge in Tabelle 2 zu meiner ID in der Spalte A den Wert 1 hat, gib mir Werte aus dieser Zeile zurück. Gibt es keinen mit dem Wert 1 in Spalte A, aber einen mit dem Wert 3, dann die Einträge aus dieser Zeile, sonst nimm den mit 2. Wenn es alle drei nicht gibt, gib NULL zurück.

    Hier stehe ich gerade völlig auf dem Schlauch & wäre für Hilfe dankbar. Hoffe, ich habe das Problem halbwegs verständlich beschrieben.

    Datenbank ist SQL Server 2012
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Zeig doch einfach mal ein kleines Beispiel, was steht in den Tabellen und was soll rauskommen.

    Andreas
     
  3. abenteurer

    abenteurer Benutzer

    in Tabelle 1 habe ich Kunden:

    ID | Name
    ---------------
    1 | Name1
    2 | Name2
    3 | Name3
    4 | Name4


    in Tabelle 2 die dazugehörenden Adressen mit eine Adressart:

    ID| Kunden_ID | Adressart | Strasse etc.
    -----------------------------------------------
    1 | 1 |4 |xxx
    2 | 1 | 3 |yyy
    3 | 2 |1 |zzz
    4 | 2 |3 |aaa
    5 | 3 |3 |bbb

    Nun will ich immer nur eine Adresse in der Ausgabe haben und zwar wo vorhanden die mit der Adressart 4, falls es die zu einem Kunden nicht gibt, dann die mit der 1, sonst die 3. Wenn keine der drei vorhanden Null.

    Gewünschtes Ergebnis:

    Name1 xxx
    Name2 zzz
    Name3 bbb
    Name4 NULL

    Verständlicher?
     
  4. ukulele

    ukulele Datenbank-Guru

    Code:
    SELECT    *
    FROM    kunden k
    LEFT JOIN adressen a ON a.Kunden_ID = k.ID
    WHERE    a.adressart = 4
    OR        a.adressart = 1
    AND NOT EXISTS    (    SELECT    1
                        FROM    adressen
                        WHERE    Kunden_ID = k.ID
                        AND        adressart = 4 )
    OR        a.adressart = 3
    AND NOT EXISTS    (    SELECT    1
                        FROM    adressen
                        WHERE    Kunden_ID = k.ID
                        AND    (    adressart = 4
                        OR        adressart = 1 ) )
    Ich weiss nicht ob das von der Performance her problematisch ist aber das wäre ein Ansatz.
     
  5. abenteurer

    abenteurer Benutzer

    das ist auf alle Fälle schon mal ein guter Ansatz, danke! Performance sollte in dem Fall nicht das Problem sein, die Abfrage wird nur alle paar Wochen benötigt.

    Das einzige Problem ist, dass ich nun für Kunden ohne Adresse keine Ausgabe bekomme statt der gewünschten NULL.
     
  6. abenteurer

    abenteurer Benutzer

    die letzte Lösung noch selbst gefunden: wenn ich die Einschränkung in den Join packe statt in die Where Klausel bekomme ich auch meine gewünschten NULL-Zeilen.
    Dankeschön!

    Wobei ich froh bin, dass es bei mir nur 3 Werte sind, die nacheinander abgefragt werden sollen und nicht 10....
     
  7. ukulele

    ukulele Datenbank-Guru

    Ansonsten könnte man sich noch eine Sicht basteln die immer nur den "interessantesten" Datensatz liefert. Da gibt es sicher noch andere Ansatzmöglichkeiten. Auf jedenfall müsste man aber eine Art Funktion schreiben um die Wertigkeit zu ermitteln, ob das dann 3, 10 oder 100 Faktoren sind wäre egal :)
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Da wir ja mit Datenbanken und Tabellen zu tun haben, denke ich, mit einer Tabelle die die Werte und Wertigkeiten beinhaltet wäre eine relativ dynamische Lösung machbar, die bei einer mehrstelligen Anzahl von Bedingungen noch immer lesbar bleibt...

    Andreas
     
  9. abenteurer

    abenteurer Benutzer

    Ich komme mit der Abfrage so zwar hin, bin aber immer neugierig ;-)
    Wie würde denn so eine Tabelle aussehen müssen, damit sie hinterher sinnvoll in die Abfrage eingebaut werden kann?
     
  10. akretschmer

    akretschmer Datenbank-Guru

    Gern doch, Lösung aber in PostgreSQL:

    Also, ich habe Deine Tabellen und noch eine extra t3, welche in a Deine Adressart und in o die Wertung hat:

    Code:
    test=*# select * from t1;
     id | name
    ----+-------
      1 | name1
      2 | name2
      3 | name3
      4 | name4
    (4 rows)
    
    Time: 0,152 ms
    test=*# select * from t2;
     id | kunde | adressart | str
    ----+-------+-----------+-----
      1 |     1 |         4 | xxx
      2 |     1 |         3 | yyy
      3 |     2 |         1 | zzz
      4 |     2 |         3 | aaa
      5 |     3 |         3 | bbb
    (5 rows)
    
    Time: 0,159 ms
    test=*# select * from t3;
     a | o
    ---+---
     4 | 1
     1 | 2
     3 | 3
    (3 rows)
    
    Nun ein kleiner Zauberspruch:

    Code:
    test=*# select t1.name, foo.str from t1 left join (select *, row_number() over (partition by kunde order by o asc) from t2 left join t3 on t2.adressart=t3.a) foo on t1.id=foo.kunde and foo.row_number = 1;
     name  | str
    -------+-----
     name1 | xxx
     name2 | zzz
     name3 | bbb
     name4 |
    (4 rows)
    

    Andreas
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden