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 SQL Abfrage 'Not In'

Dieses Thema im Forum "Oracle" wurde erstellt von mustangsls, 13 Juni 2012.

  1. mustangsls

    mustangsls Benutzer

    Guten Tag.

    Bin neu hier und komm jetzt öfter.
    Darf mich im Wirtschaftsinformatik Studium mit dem SQL Developer auseinandersetzen und hab noch ein paar Startschwierigkeiten. Hoffe ich finde hier jetzt regelmäßig Hilfe. Stehe auch gern mit Tips zur Verfügung wenn ich selbst welche geben kann.

    So nun zum Problem:

    Ich möchte mehrere Playlists mit dem Namen 'Classical %' nach Tracks des Genres 'Classical' durchsuchen, die nicht in diesen Playlists auftauchen.

    Soweit bin ich bisher, stehe aber jetzt irgendwie auf dem Schlauch:

    select tr.name
    from track tr,
    genre ge,
    playlist pl
    where pl.name = 'Classical%' and
    ge.name not in ('Classical')
    ;

    Ich hänge das passende Modell mal mit an.

    Achso, es muss nicht unbedingt mit 'Not In' gelöst werden, erschien mir nur sinnvoll.
     

    Anhänge:

  2. PLSQL_SQL

    PLSQL_SQL Datenbank-Guru

    Hy,

    dein SQL-Stmt ist nicht schlecht, jedoch solltest du die Relationen (Beziehungen) des angehängten Modells in deiner Abfrage berücksichtigen!!!
    Ansonsten joinst du ALLE Datensätze der 3 Tabellen mit ALLEN der 3 Tabellen. Weiters fehlt dir noch die Tabelle "PLAYLISTTRACK", da du nur über diese von einem Track zur Playlist kommst, denn EINE Playlist kann mehrere Track beinhalten, und EIN Track kann in mehreren Playlists sein!

    Daraus folgt: M:N - Beziehung und diese muss (wie es eh schon richtig ist) aufgelöst werden. Somit musst du die Tabelle "PLAYLISTTRACK" mit berücksichtigen!

    So.... so viel zu Erklärung, hoffentlich einigermaßen verständlich...

    Hier dein Stmt:

    Code:
     
    Select pl.Name AS PlaylistName
              tr.Name AS TrackName
     
      FROM PlayList pl
                ,PlayListTrack plt
                ,Track tr
                ,Genre ge
     
    --die Beziehungen (Joins) der Tabellen
    where pl.PlayListID = plt.PlayListID
    AND plt.TrackID = tr.TrackID
    AND tr.GenreID = ge.GenreID
     
    --deine gewünschte Filterung kommt ab hier
    AND pl.Name LIKE 'Classical%' --nur jene Playlists, welche mit dem Wort "Classical" beginnen
    AND ge.Name LIKE 'Classical' --nur jene Tracks, welche dem Genre "Classical" zugewiesen sind!
     
    
    passt dieses Query für dich, oder habe ich das richtig verstanden, dass du ALLE Tracks möchtest, welche als Genre "Classical" zugeordnet haben, jedoch in KEINER Playlist beginnend mit "Classical" sitzen?

    LG
     
  3. mustangsls

    mustangsls Benutzer

    Hallo :)
    Das funktioniert ja schonmal blendend. Vielen Dank.

    Aber ja, du hast es richtig verstanden. Ich brauche alle 'Classical'-Tracks die nicht in den 'Classical 101'-Playlists sind.

    Also so funktioniert es schonmal nicht richtig:

    Code:
    Select tr.Name
     
    FROM PlayList pl,
     
    PlayListTrack plt,
     
    Track tr,
     
    Genre ge
     
    where pl.PlayListID = plt.PlayListID AND
     
    plt.TrackID = tr.TrackID AND
     
    tr.GenreID = ge.GenreID AND
     
    pl.Name LIKE 'Classical%' AND
     
    ge.Name not in ('Classical')
     
    ;
     
  4. mustangsls

    mustangsls Benutzer

    Bin jetzt soweit, das ich ne Unterabfrage brauch. Hänge jetzt soweit noch fest:

    Code:
    Select  tr.name       
    FROM    Track tr, Genre ge 
    where  ge.name = 'Classical'
    AND    tr.name NOT IN
            ( select tr.name 
              from    track tr, 
                      PlayList pl, 
                      PlayListTrack plt 
              where  pl.Name LIKE 'Classical%')
    ;
     
  5. mustangsls

    mustangsls Benutzer

    Geschafft!!! Der Hirnknoten ist endlich geplatzt ;-)

    Code:
    Select  tr.name       
    FROM    Track tr, Genre ge 
    where  ge.name = 'Classical'
    AND    tr.GenreID = ge.GenreID
    AND    tr.name NOT IN
            ( select tr.name 
              from    track tr, 
                      PlayList pl, 
                      PlayListTrack plt 
              where  pl.Name LIKE 'Classical%'
              AND pl.PlayListID = plt.PlayListID
              AND plt.TrackID = tr.TrackID)
    ;
     
  6. PLSQL_SQL

    PLSQL_SQL Datenbank-Guru

    Perfekt!!! Super!!!

    Aber aus schönheitstechnischen und/oder performance-Gründen würde ich anstatt des Track-Namens die TrackID heranziehen.

    Code:
     
    Select tr.name
    FROM Track tr, Genre ge
    where ge.name = 'Classical'
    AND tr.GenreID = ge.GenreID
    AND tr.TrackID NOT IN
    ( select tr.TrackID
    from track tr,
    PlayList pl,
    PlayListTrack plt
    where pl.Name LIKE 'Classical%'
    AND pl.PlayListID = plt.PlayListID
    AND plt.TrackID = tr.TrackID)
    ;
     
    
    Noch besser als "NOT IN" ist "NOT EXISTS"


    Code:
     
    Select tr.name
    FROM Track tr, Genre ge
    where ge.name = 'Classical'
    AND tr.GenreID = ge.GenreID
    AND NOT EXISTS
    ( select 1 --hier ist egal was du in die Select-Klause schreibst, da die Unterabfrage nur verwendet wird, um zu prüfen, ob etwas existriert oder nicht
    from track trsub,
    PlayList plsub,
    PlayListTrack pltsub
    where plsub.Name LIKE 'Classical%'
    AND plsub.PlayListID = pltsub.PlayListID
    AND pltsub.TrackID = tr.TrackID --Join der Subabfrage mit der äußeren!!!
    )
    ;
     
    
    LG
     
    Walter gefällt das.
  7. mustangsls

    mustangsls Benutzer

    Alles klar. Vielen Dank für die super Unterstützung :)
    Melde mich bestimmt bald wieder ;-)
     
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