1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Filtern von Datensätzen

Dieses Thema im Forum "Oracle" wurde erstellt von FrenchSpirit, 13 September 2017.

  1. FrenchSpirit

    FrenchSpirit Benutzer

    Hallo an alle SQL-Experten,

    ich habe folgende Tabelle:

    KDNR NAME KFZ
    4711 Anton BMW
    4612 Berta BMW
    4612 Berta AUDI
    4813 Cäsar AUDI

    In dem Selekt möchte ich alle Kunden geliefert bekommen, die KEINEN AUDI haben.

    Das schwierige für mich ist im Beispiel der Kunde "Berta", der mehrere Marken hat. Wenn ich im Selekt sage WHERE KFZ NOT LIKE 'AUDI', wird Berta dennoch in der Trefferliste auftauchen, da sie ja mit der Zeile "BMW" gefunden wird. Ich möchte die Kundennummer 4612 allerdings komplett ausschließen.


    Vielen Dank vorab für eure Hilfe

    Gruß

    Andreas
     
  2. akretschmer

    akretschmer Datenbank-Guru

    folgendes geht mit PostgreSQL:

    Code:
    test=# select * from autos ;
     kdnr | name  | kfz  
    ------+-------+------
     4711 | anton | bwm
     4612 | berta | bmw
     4612 | berta | audi
     4813 | cäsar | audi
    (4 rows)
    
    test=# with tmp_autos as (select name, array_agg(kfz) from autos group by name) select name, array_to_string(array_agg,', ') from tmp_autos where not array_agg  @> array['audi'];
     name  | array_to_string
    -------+-----------------
     anton | bwm
    (1 row)
    
    test=#
    
    kann das Oracle?
     
  3. akretschmer

    akretschmer Datenbank-Guru

    und folgendes geht vermutlich auch mit oracle:

    Code:
    test=# select distinct name from autos except select name from autos where kfz = 'audi';
     name  
    -------
     anton
    (1 row)
    
     
  4. drdimitri

    drdimitri Datenbank-Guru

    Klar geht das aber der Operator heißt MINUS
     
  5. FrenchSpirit

    FrenchSpirit Benutzer

    Vielen lieben Dank an euch beide.

    Folgendes hat funktioniert:

    SELECT DISTINCT name
    FROM autos
    MINUS SELECT name from autos WHERE kfz = 'audi'


    Viele Grüße

    Andreas
     
  6. FrenchSpirit

    FrenchSpirit Benutzer

    Hallo in die Runde,
    leider muss ich meinen SQL noch um eine weitere Tabelle erweitern.
    Neben der Tabelle mit den Autos, wo ich die "Audis" eliminiert habe, gibt es eine zweite Tabelle mit Verbünden:

    Tabelle 2:
    KDNR NAME VERBUND
    4711 ANTON 1234
    9977 ANTONS FRAU 1234
    0815 MICHAEL 5678
    9612 MARKUS 3567

    Wenn nun in der Tabelle 1 Anton zwar keinen Audi hat, aber ggf. in der Tabelle Antons Frau einen Audi fährt, sollen sowohl Anton als auch seine Frau rausfallen.

    Ich möchte also nur die Personen ohne Audi haben, die im gesamten Verbund keinen Audi fahren. In Tabelle 2 kann ich die relevanten Personennummer über die Verbundnummer erweitern. Ich bekomme es aber nicht hin, dass er die Kundennummern 4711 bzw. 9977 nur auswirft, wenn beide KEINEN audi haben...

    Viele Grüße und wiedermal dank vorab

    Andreas
     
  7. ukulele

    ukulele Datenbank-Guru

    Eine Möglichkeit wäre z.B.
    Code:
    SELECT   DISTINCT name
    FROM   autos
    WHERE   KFZ <> 'audi'
    AND     KDNR NOT IN (
    SELECT   t1.KDNR
    FROM   tabelle2 t1
    INNER JOIN tabelle2 t2
    ON     t1.VERBUND = t2.VERBUND
    AND     t1.KDNR <> t2.KDNR
    INNER JOIN autos a
    ON     t2.KDNR = a.KDNR
    WHERE   a.KFZ = 'audi' )
    
     
  8. FrenchSpirit

    FrenchSpirit Benutzer

    Hallo, ukulele,
    vielen Dank für die super schnelle Antwort.
    Ich habe den Selekt mit meinen Echttabellen nachgebaut. Der erste Treffer war leider ein Kunde mit "Audi". Ich habe in deinem Selekt in der letzten Zeile aus dem a.kfz = 'audi' ein a.kfz <>'audi' gemacht. Oder hab ich einen Denkfehler?

    Gruß
    Andreas
     
  9. ukulele

    ukulele Datenbank-Guru

    Das wäre nicht richtig da ich mit NOT IN (Subselect) alle KDNR ausschließen will die über den VERBUND einen Einrag mit KFZ = Audi zugeordnet haben.

    Das Problem entsteht bei der Veränderung des ursprünglichen Codes, richtiger wäre:
    Code:
    SELECT DISTINCT name
    FROM autos
    WHERE KDNR NOT IN (
    SELECT t1.KDNR
    FROM tabelle2 t1
    INNER JOIN tabelle2 t2
    ON t1.VERBUND = t2.VERBUND
    AND t1.KDNR <> t2.KDNR
    INNER JOIN autos a
    ON t2.KDNR = a.KDNR
    WHERE a.KFZ = 'audi' )
    MINUS
    SELECT NAME
    FROM autos
    WHERE KFZ = 'audi'
    
    Also wieder mit MINUS da ein Kunde ja mehrere Autos haben kann und davon keins ein Audi sein soll. Allerdings mag ich diese Lösung nicht, da MINUS nach NAME unscharf ist. Was ist wenn zwei Kunden mit unterschiedlicher KDNR (Primärschlüssel, eindeutig) den selben Namen haben? Daher würde ich dann doch zu dem hier raten:
    Code:
    SELECT DISTINCT name
    FROM autos
    WHERE KDNR NOT IN (
    SELECT t1.KDNR
    FROM tabelle2 t1
    INNER JOIN tabelle2 t2
    ON t1.VERBUND = t2.VERBUND
    AND t1.KDNR <> t2.KDNR
    INNER JOIN autos a
    ON t2.KDNR = a.KDNR
    WHERE a.KFZ = 'audi' )
    AND KDNR NOT IN (
    SELECT DISTINCT KDNR
    FROM autos
    WHERE KFZ = 'audi' )
    
     
  10. FrenchSpirit

    FrenchSpirit Benutzer

    Hallo, Ukulele,
    ich baue gerade deinen letzten Selekt nach. In der Mitte vergibst du meiner Tabelle autos den Alias "a". Im ersten Selektbereich und ganz am Ende nennst Du die Tabelle nur autos und vergibst auch vor den Feldern KDNR und KFZ keinen alias. ist das richtig, oder muss die Tabelle, da sie 3mal vorkommt, 3 verschiedene alias-namen erhalten?
    Gruß
    Andreas
     
  11. ukulele

    ukulele Datenbank-Guru

    Das wäre nicht richtig da ich mit NOT IN (Subselect) alle KDNR ausschließen will die über den VERBUND einen Einrag mit KFZ = Audi zugeordnet haben.

    Das Problem entsteht bei der Veränderung des ursprünglichen Codes, richtiger wäre:
    Code:
    SELECT DISTINCT name
    FROM autos
    WHERE KDNR NOT IN (
    SELECT t1.KDNR
    FROM tabelle2 t1
    INNER JOIN tabelle2 t2
    ON t1.VERBUND = t2.VERBUND
    AND t1.KDNR <> t2.KDNR
    INNER JOIN autos a
    ON t2.KDNR = a.KDNR
    WHERE a.KFZ = 'audi' )
    MINUS
    SELECT NAME
    FROM autos
    WHERE KFZ = 'audi'
    
    Also wieder mit MINUS da ein Kunde ja mehrere Autos haben kann und davon keins ein Audi sein soll. Allerdings mag ich diese Lösung nicht, da MINUS nach NAME unscharf ist, was ist wenn zwei Kunden mit unterschiedlicher KDNR (Primärschlüssel, eindeutig) dein selben Namen haben? Daher würde ich dann doch zu dem hier raten:
    Code:
    SELECT DISTINCT name
    FROM autos
    WHERE KDNR NOT IN (
    SELECT t1.KDNR
    FROM tabelle2 t1
    INNER JOIN tabelle2 t2
    ON t1.VERBUND = t2.VERBUND
    AND t1.KDNR <> t2.KDNR
    INNER JOIN autos a
    ON t2.KDNR = a.KDNR
    WHERE a.KFZ = 'audi' )
    AND KDNR NOT IN (
    SELECT KDNR
    FROM autos
    WHERE KFZ = 'audi' )
    
     
Die Seite wird geladen...

Diese Seite empfehlen