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

Problem mit komplizierter SQL-Abfrage (NOT IN - NOT EXITS...)

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von Twistor, 12 Juni 2018.

  1. Twistor

    Twistor Benutzer

    Hallo Community,

    seit drei Tagen hänge ich jetzt schon an einer, zumindest für mich komplizierten, SQL-Abfrage und komm nicht weiter. Ich versuche mal mein Problem und meine Tabellen zu skizzieren.

    Tabelle1:
    VID | _PID | _UID | STATUS
    3075 | 6508 | 535 | 1
    3076 | 6509 | 535 | 1
    3077 | 6510 | 535 | 1
    3078 | 6511 | 535 | 1

    Tabelle2:

    DID | _VID | _UID | FIRMA
    763 | 3075 | 535 | Firma 1
    764 | 3076 | 535 | Firma 1
    765 | 3076 | 535 | Firma 2
    766 | 3076 | 535 | Firma 3
    767 | 3077 | 535 | Firma 1
    768 | 3077 | 535 | Firma 2


    So, das sind meine Tabellen und deren Inhalte.
    Jetzt möchte ich eine Abfrage bastelen die die Einträge (_VID) aus Tabelle 2 findet welche Firma 3 nicht enthält, außerdem müsste der SELECT auch noch die VID 3078 aus Tabelle 1 finden weil zu dem Eintrag ja auch Firma 3 nicht existiert (Das gewünschte Ergebnis habe ich oben mal FETT gemacht).
    Ich habe hier schon wirklich einige Lösungsansätze versucht und ausprobiert und sehr viel gegoogelt, aber leider komme ich nicht weiter, deswegen hoffe ich jetzt auf euch.
    Meine Lösungsansätze poste ich jetzt der einfachheit mal nicht mit dazu, wenn gewünscht kann ich sie noch hinzufügen.

    Ich hoffe ihr versteht mein Problem und könnt mir weiterhelfen, vorab schonmal vielen Dank.

    Liebe Grüße
    Twistor
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Deine 2 Tabellen haben einen unterschiedlichen Aufbau, da wird es schwer, die 4 markierten Zeilen in einem Result zu erhalten, so wie gezeigt. Wenn es Dir nur um die VID-Spalte geht:

    Code:
    test=*# select * from t1;
     vid  | pid  | uid
    ------+------+-----
     3075 | 6508 | 535
     3076 | 6509 | 535
     3077 | 6510 | 535
     3078 | 6511 | 535
    (4 Zeilen)
    
    test=*# select * from t2;
     did | vid  | uid |  firma  
    -----+------+-----+---------
     763 | 3075 | 535 | firma 1
     764 | 3076 | 535 | firma 1
     765 | 3076 | 535 | firma 2
     766 | 3076 | 535 | firma 3
     767 | 3077 | 535 | firma 1
     768 | 3077 | 535 | firma 2
    (6 Zeilen)
    
    test=*# with tmp as (select vid, array_agg(firma) from t2 group by vid having not array_agg(firma) @> array['firma 3']), tmp2 as (select vid from t2 where firma = 'firma 3') select vid from tmp union all select vid from t1 where vid not in (select vid from tmp union select vid from tmp2);
     vid  
    ------
     3077
     3075
     3078
    (3 Zeilen)
    
    test=*#
    
    Du mußt jetzt aber ganz tapfer sein: ich verwende PostgreSQL, ob MySQL das so auch kann kann bezweifelt werden.
     
  3. Twistor

    Twistor Benutzer

    Vielen Dank für deine Hilfe, aber leider bekomm ich das so in MySQL nicht hin, zumindest wüsste ich nicht wie. Na ja ich werde jetzt noch etwas abwarten ob mir hier noch jemand weiterhelfen kann, wenn nicht dann werd ich wohl das ganze dann über PHP lösen
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Geht dies?

    Code:
    test=# select distinct vid from t2 except select distinct vid from t2 where firma = 'firma 3' union all (select vid from t1 where vid not in(select distinct vid from t2));
     vid  
    ------
     3077
     3075
     3078
    (3 Zeilen)
    
    Das ist Standard-SQL, seit 30 Jahren oder so ...
     
  5. Twistor

    Twistor Benutzer

    Leider wird "except" nicht von MySQL unterstützt, deswegen bekomm ich mit deinem SELECT einen ERROR... Ich hab es mal versucht umzubauen auf NOT IN aberda bekomm ich dann leider die falschen Zeilen

    select distinct vid from t2 WHERE firma NOT IN (select distinct vid from t2 where firma = 'firma 3' union all (select vid from t1 where vid not in(select distinct vid from t2)));

    ------
    3075
    3076
    3077
    (3 Zeilen)

    3076 ist zuviel und 3078 fehlt...

    Hast du noch eine Idee? Wenn nicht, dann geh ich über und löse es in PHP

    Vielen Dank und viele Grüße,
    Twistor
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Das ist auch bullshit, sorry:

    Code:
    test=*# select distinct vid from t2 WHERE firma NOT IN (select distinct vid from t2 where firma = 'firma 3' union all (select vid from t1 where vid not in(select distinct vid from t2)));
    FEHLER:  Operator existiert nicht: text = integer
    ZEILE 1: select distinct vid from t2 WHERE firma NOT IN (select disti...
                                                     ^
    TIP:  Kein Operator stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen.
    test=*#
    
     
  7. Twistor

    Twistor Benutzer

    :D Das dachte ich mir schon :D
     
    akretschmer gefällt das.
  8. Twistor

    Twistor Benutzer

    Na ja ich denke ich werde hier mit einem SELECT nicht weiterkommen . Ich denke ich werde es umbauen und über PHP lösen. Falls doch ncoh jemand eine Lösung findet würde ich mich freuen.

    Vielen Dank!
     
  9. akretschmer

    akretschmer Datenbank-Guru

    ... was natürlich die schlechteste aller Lösungen ist. Daten aus der DB raus in die Anwendung, dort suchen. Das skaliert nicht, sobald die Datenmengen größer werden, knallt das gegen die Wand.
     
  10. Twistor

    Twistor Benutzer

    Welchen Lösungsansatz würdest du dann Vorschlagen?
     
  11. akretschmer

    akretschmer Datenbank-Guru

    Ich nannte 2 ;-)

    Gut, Du müßtest halt die DB wechseln...
     
  12. Twistor

    Twistor Benutzer

    :D Prinzipiell nicht verkehrt nur das Problem ist hier das es sich um eine ziemlich große Anwendung handelt und der Arbeitsaufwand hierfür sehr enorm wäre. Daher ist das leider nicht möglich.
     
  13. Twistor

    Twistor Benutzer

    So also ich hab jetzt nochmal rumprobiert und ich denke ich habe doch eine Lösung gefunden, aber hätte hier gerne noch eine experten Meinung zu :D

    SELECT
    *
    FROM tabelle1 AS t1
    WHERE t1.VID != (
    SELECT
    t2.VID
    FROM
    tabelle1 AS t1
    LEFT JOIN tabelle2 AS t2 ON (t1.VID = t2.VID)
    WHERE t2.FIRMA = "Firma 3");

    ------
    3077
    3075
    3078
    (3 Zeilen)

    Edit: Funktioniert auch nicht da der Subquery mehr als ein reultat liefer kann. MIST

    Aber wenn ich anstatt != NOT IN verwende müsste es doch funktionieren oder was meint Ihr?

    Also sprich:

    SELECT
    *
    FROM tabelle1 AS t1
    WHERE t1.VID NOT IN (
    SELECT
    t2.VID
    FROM
    tabelle1 AS t1
    LEFT JOIN tabelle2 AS t2 ON (t1.VID = t2.VID)
    WHERE t2.FIRMA = "Firma 3");
     
    akretschmer gefällt das.
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