Thes: Join, Subselect

Hallo,

ich habe folgende Tabellen (vereinfacht):

1.
Name: threads
Spalte: ID

2.
Name: has_read
Spalte: threads_id
Spalte: user_id

In der has_read-Tabelle existiert nur dann ein Eintrag, wenn
der Benutzer einen bestimmten Beitrag bereits gelesen hat.

Nun moechte ich gerne ein Statement absetzen, welches mir fuer
einen Benutzer die Anzahl aller noch nicht gelesenen Threads liefert.

Das heisst, ich muesste ein SELECT auf die threads-Tabelle machen,
welches mir alle Eintraege liefert, die noch keinen Eintrag in
der has_read-Tabelle besitzen.

Nun meine Frage: Wie realisiere ich das am Besten?
Outerjoin, Subselects?

Danke fuer eure Hilfe
Thes

  1. Hallo,

    ich habe folgende Tabellen (vereinfacht):

    Name: threads
    Spalte: ID

    Name: has_read
    Spalte: threads_id
    Spalte: user_id

    Würde es nicht ein

    select threads.id, has_read.threads from threads left join has_read on threads.id = has_read.threads_id WHERE has_read.user_id != $USER_ID

    tun?

    1. Hallo,

      zuerst einmal Danke fuer deinen Beitrag.

      select threads.id, has_read.threads from threads left join has_read on threads.id = has_read.threads_id WHERE has_read.user_id != $USER_ID

      Also wenn ich das Script ausfuehre, so bekomme ich ein leeres Resultset (was aber nicht an dem Inhalt der Tabellen liegen kann).

      Gruesse
      Thes

  2. Hallo

    Nun moechte ich gerne ein Statement absetzen, welches mir fuer
    einen Benutzer die Anzahl aller noch nicht gelesenen Threads liefert.

    Nun meine Frage: Wie realisiere ich das am Besten?
    Outerjoin, Subselects?

    Erstelle beide Statements und überprüfe die Performance mit EXPLAIN.
    Führe die Überprüfung von Zeit zu Zeit erneut durch.

    Ich gehe davon aus, dass Du die relevanten Spalten mit einem
    Index versehen hast.

    Freundliche Grüße

    Vinzenz

    1. Hallo Vinzenz,

      Erstelle beide Statements

      Hm, genau da liegt ja mein Problem ;)

      und überprüfe die Performance mit EXPLAIN.

      OK, danke. Das kannte ich noch nicht.

      Ich gehe davon aus, dass Du die relevanten Spalten mit einem
      Index versehen hast.

      Ja.

      Gruesse
      Thes

  3. Hallo,

    also es geht wohl auch leichter:

      
    SELECT count(m.id)  
    FROM msgs_threads m  
    WHERE NOT EXISTS  
     (SELECT h.hasread FROM hasread h  
      WHERE h.tblentryid=m.id AND h.member_id=1);  
    
    

    Oder gibt es hierbei irgendwelche - mir unbekannten - Einwaende?

    Thes

    1. Hallo

      also es geht wohl auch leichter:

      SELECT count(m.id)
      FROM msgs_threads m
      WHERE NOT EXISTS
      (SELECT h.hasread FROM hasread h
        WHERE h.tblentryid=m.id AND h.member_id=1);

      
      >   
      > Oder gibt es hierbei irgendwelche - mir unbekannten - Einwaende?  
        
      Du könntest es mit der Query vergleichen, die ich Dir vorschlagen wollte,  
      dann aber gesehen hatte, dass Du den Thread bereits auf SOLVED gesetzt  
      hattest.  
        
      ~~~sql
      SELECT                           -- Gib die Anzahl aller  
           COUNT(ID) AS Anzahl         -- ID-Werte  
      FROM threads                     -- aus der Tabelle threads  
      WHERE ID NOT IN (                -- die nicht in der Liste  
          SELECT  
              threads_id               -- der id-s sind  
          FROM has_read                -- die bereits gelesen wurden  
          WHERE user_id = <dein user>  -- vom Benutzer  
      )  
      
      

      Bitte keine Anmerkungen zur Grammatik meiner Kommentare :-)

      Freundliche Grüße

      Vinzenz

      1. Hallo Vinzenz,

        danke. Das spart nochmal um die 0.3 Sekunden!

        Gruesse
        Thes