2011-01-03 4 views
0

Ok das (abgeschnittene Abfrage) läuft gut. Habe vor einem Monat einen Expertenrat bekommen, um es zu reparieren."Dreiergruppe"? Kann ein INNER-JOIN eine zusätzliche Abfrage nach 'WHERE' haben, um Zeilen aus einer dritten Tabelle auszuschließen?

SELECT * FROM artWork WHERE art_id in (
    SELECT art_id FROM artWork AS a INNER JOIN userPrefs AS u ON ((
     ((u.media_oil='1' AND a.media_oil='1') OR 
     (u.media_acrylic='1' AND a.media_acrylic='1') OR 
     (u.media_wc='1' AND a.media_wc='1') OR 
     (u.media_pastel='1' AND a.media_pastel='1')) 

     etc, etc........................................ 

    WHERE a.artist_id NOT EXISTS (
     SELECT * FROM removeList AS r 
     WHERE r.artist_id = a.artist_id 
      AND r.user_id ='$user_id') 
      AND a.make_avail='1' 
      AND a.cur_select='1' 
      AND u.user_id='$user_id' 
      AND ((u.pref_painting='1' AND a.pref_painting='1') OR 
       (u.pref_photo='1' AND a.pref_photo='1') OR 
       (u.pref_paper='1' AND a.pref_paper='1') OR 
       (u.pref_print='1' AND a.pref_print='1') OR 
       (u.pref_draw='1' AND a.pref_draw='1') OR 
       (u.pref_sculp='1' AND a.pref_sculp='1') OR 
       (u.pref_install='1' AND a.pref_install='1') OR 
       (u.pref_vid='1' AND a.pref_vid='1') OR 
       (u.pref_public='1' AND a.pref_public='1') OR 
       (u.pref_indef='1' AND a.pref_indef='1')) 
    ) ORDER BY date_submit DESC 

Aber jetzt brauche ich bestimmte Zeilen auszuschließen, die in einem anderen 2-Säule (user_id & KUENSTLER_ID) Kind Tisch sein können: ‚removeList‘. Also versuche ich, ohne Erfolg, was beläuft sich auf eine „Triple-Join“ (suchen Sie nach dem Code um 'NICHT VORHANDEN):

SELECT * FROM artWork WHERE art_id in (
    SELECT art_id FROM artWork AS a INNER JOIN userPrefs AS u ON ( 
      (((u.media_oil='1' AND a.media_oil='1') OR 
       (u.media_acrylic='1' AND a.media_acrylic='1') OR 
       (u.media_wc='1' AND a.media_wc='1') OR 
       (u.media_pastel='1' AND a.media_pastel='1')) 

       etc, etc........................................ 


    WHERE a.artist_id NOT EXISTS (
     SELECT * FROM removeList AS r 
     WHERE r.artist_id = a.artist_id AND r.user_id ='$user_id' 
    ) 
    AND a.make_avail='1' 
    AND a.cur_select='1' 
    AND u.user_id='$user_id' 
    AND ((u.pref_painting='1' AND a.pref_painting='1') OR 
     (u.pref_photo='1' AND a.pref_photo='1') OR 
     (u.pref_paper='1' AND a.pref_paper='1') OR 
     (u.pref_print='1' AND a.pref_print='1') OR 
     (u.pref_draw='1' AND a.pref_draw='1') OR 
     (u.pref_sculp='1' AND a.pref_sculp='1') OR 
     (u.pref_install='1' AND a.pref_install='1') OR 
     (u.pref_vid='1' AND a.pref_vid='1') OR 
     (u.pref_public='1' AND a.pref_public='1') OR 
     (u.pref_indef='1' AND a.pref_indef='1')) 
    ) ORDER BY date_submit DESC 

Bin ich hier zu weit reichend? Gibt es einen besseren Ansatz, den ich übersehe? Dank an alle.

+0

Wow. Und * das ist abgeschnitten? –

Antwort

1

NOT EXISTS sollte keinen Spaltennamen davor haben. entferne die a.artist_id von vor dem nicht existiert.

So ist die entsprechende Zeile würde sagen

WHERE NOT EXISTS (
    SELECT * FROM removeList AS r 
    WHERE r.artist_id = a.artist_id AND r.user_id ='$user_id' 
) 

nicht sicher, wo Sie diese Abfrage verwenden, aber es ist auch Ihre Anfragen empfohlen zu parametrieren SQL-Injektionen zu verhindern.

Hoffe, das hilft!

+0

Danke! Arbeitete am ersten Schuss. Auch fyi, nicht gezeigt, ist, dass die gesamte Abfrage in einer Variablen gespeichert und verwendet wird, um Zeilen in Standardform zu ziehen, um in einer dynamischen Liste zu echo. Dies ist das zweite Mal, dass Sie meinen Code verhalten. wirklich schätzen, ehudokai – artworthy

0

Ich weiß, das ist keine Antwort, aber ich konnte keine Tabelle in den Kommentaren platzieren, also setze ich es hier.

Ich habe das Gefühl, dass zusätzliche Tabellen für Ihre Medien und Einstellungen hier benötigt werden, um die Dinge in Ihrer Datenbank zu vereinfachen.

Dann Felder in Ihrer Kunst-Tabelle, die zu einem Medientyp und Pref-Typ korrelieren.

art_table 
media_type, art_type 

Auf diese Weise können Sie einfach einen einfachen JOIN verwenden, um korrelierende Datensätze anstelle von Hunderten von Vergleichen zu finden.

SELECT art.id FROM art JOIN prefs_table ON art.pref_type = prefs_table.pref_type JOIN users ON prefs_table.user_id = users.id WHERE users.id = whatever 

Dies ist ein vereinfachtes Beispiel, das alle Peices Kunst ziehen würde, dass irgendeine der die Vorlieben des Benutzers angepasst. Sie könnten natürlich auch Medientypen problemlos in die gleiche Abfrage auf die gleiche Weise integrieren.

0

Sie müssen einige ernsthafte Arbeit an Ihrem Schema, entlang der von dqhendricks vorgeschlagenen Linien tun.

Sie haben 3 Tabellen:

  • ArtWork (ART_ID, KUENSTLER_ID, ... Eigenschaften ...)
  • UserPrefs (User_ID, ... Eigenschaften ...)
  • RemoveList (KUENSTLER_ID User_ID),

Sie wollen Kunstwerke aufzuzählen, die die Benutzereinstellungen eines bestimmten Benutzers entsprechen, wollen aber nicht alle Kunstwerke aufzuzählen, in denen der Künstler den Benutzer nicht mag, oder der Benutzer nicht mag den Künstler (oder beide) .

Sie sollten daher in der Lage so etwas wie zu tun:

SELECT A.* 
    FROM ArtWork AS A 
    JOIN UserPrefs AS U 
    ON (U.User_ID = ? AND (...ghastly OR'd join conditions...)) 
WHERE A.Artist_ID NOT IN (SELECT R.Artist_ID 
          FROM RemoveList AS R 
          WHERE R.User_ID = ?) 

Beachten Sie, dass einige der Join-Bedingungen in der WHERE-Klausel, und verschiedene andere Änderungen, aber die Grundstruktur der Abfrage bewegen kann wird ein JOIN von ArtWork und UserPrefs und eine WHERE-Klausel mit der NOT IN-Klausel (die Sie als NOT EXISTS-Klausel schreiben könnten, aber ich denke, dass die NOT IN-Formulierung einfacher zu lesen ist).