DB-Abfrage - Aufklärung

Alice

Erfahrenes Mitglied
Hallo.

Ich habe hier eine DB-Abfrage, den ich nicht so richtig verstehe. MYSQL ist nicht so mein Gebiet. Ich hoffe, jemand kann ihn mir erklären.

Der Query funktioniert und liefert mir die Anzahl ungelesener Beiträge im Forum.

PHP:
$Foren_ID = array_keys($vbulletin->forumcache);
$Foren_ID = implode(',',$Foren_ID);
$Limit = TIMENOW - ($vbulletin->options['markinglimit'] * 86400);
$Visible = '0,1,2';
$UserID = $vbulletin->userinfo['userid'];

$postcount = $vbulletin->db->query_first_slave("
SELECT COUNT(post.postid) as unread FROM post AS post
INNER JOIN thread AS thread USING (threadid)
INNER JOIN forum AS forum USING (forumid)
LEFT JOIN threadread AS threadread ON (threadread.threadid = thread.threadid AND threadread.userid = $UserID)
LEFT JOIN forumread AS forumread ON (forumread.forumid  = forum.forumid AND forumread.userid = $UserID)
WHERE thread.forumid IN(0$Foren_ID) AND thread.visible IN ($Visible)
AND post.dateline > IF(threadread.readtime IS NULL, $Limit, threadread.readtime)
AND post.dateline > IF(forumread.readtime IS NULL, $Limit, forumread.readtime)
AND post.dateline > $Limit
AND thread.lastpost > IF(threadread.readtime IS NULL, $Limit, threadread.readtime)
AND thread.lastpost > IF(forumread.readtime IS NULL, $Limit, forumread.readtime)
AND thread.lastpost > $Limit
");

Ich möchte nicht einfach was aus dem Internet "kopieren" dessen Funktion ich nicht verstanden habe.

1.) Welche Tabellen werden angesprochen? (post, thread, forum, threadread und forumred?)
2.) Könnte man die Abfrage so umbauen, dass sie verständlicher ist? (Mehr Querie) Wie?
3.) Was bedeutet das "IN"?
4.) Was bedeutet die "0" vor $Foren_ID? (in $Foren_ID sind alle Foren ID´s mit Komma getrennt gespeichert)
 
Hi

1) Genau

2) Besser gar nicht. Überlass den harten Teil der Arbeit der DB.
Das in PHP nachzubauen wird weder ein Einzeiler noch effizient.

3) Im IN steht eine Liste von Werten, mit Komma getrennt,
und WHERE xyz IN(bla,blub) wird dann gefunden, wenn xyz einer dieser Werte ist.
Ein WHERE forumid IN(4,27,39) findet also Datensätze mit forumid 4 oder 27 oder 39.
In deiner Abfrage wird der Inhalt vom IN weiter oben mit array_keys und implode zusammengebaut.

4) Die 0 ist einfach Teil vom Text, wie das IN und die Klammer davor.
Die Art, wie der IN-Inhalt zusammengebaut wird, erzeugt vermutlich etwas, wo vor dem ersten
Wert auch schon ein Komma ist (Grund: Inhalt von $vbulletin->forumcache).
Statt einem WHERE forumid IN(4,27,39) hätte man dann ein WHERE forumid IN(,4,27,39)
und damit einen Syntaxfehler

Lösung 1: Das Komma zuerst aus dem String rausfiltern
Lösung 2: Das Forum mit ID 0 gibts vermutlich nicht, also schadet es nicht, (auch) danach zu suchen.
Und da wurde dann eben eine 0 vorne angehängt: WHERE forumid IN(0,4,27,39)
Ist kürzer als der Code zum Komma-entfernen.

Und, falls sich die Frage stellt, warum man hier kein + zur Stringverkettung braucht:
Weil die ganze SQL-Anweisung ja schon einer ist...
Entweder also "0"+$Foren_ID oder "0$Foren_ID"
Und es ist ja schon das Zweite, nur das noch mehr Text zwischen den "..." ist.
(Warum ich das erwähne, weils ja sowieso klar ist? Hab da selber zuerst herumgerätselt
warum es ohne + geht :D Ganz vergessen, dass das alles ja ein großér String ist...)
 
Zuletzt bearbeitet:
Danke für die Erklärung!

Es werden ja die 5 Tabellen angesprochen.

1.) post (Alle Beiträge)
2.) thread (Alle Themen)
3.) forum (Alle Foren)
4.) threadread (Als gelesen markierte Themen*)
5.) forumred (Als gelesen markierte Foren*)

Ich denke die Namen sind mehr oder weniger Selbsterklärend.

* Nach einigen beobachtungen gehe ich davon aus, dass hier nur Einträge zu finden sind, die nicht älter als 10 Tage sind. Ganz aktuell ist der älteste Timestamp vom 21.10.2014 und sollte morgen nicht mehr da sein.

Ich würde den DB-Query gerne erweitern, bin damit aber hoffnungslos überfordert.

Ich habe hier noch eine Tabelle mit dem Namen "subscribethread". Also Themen die von Usern beobachtet werden. Könnte mir jemand helfen, den Query so zu erweitern, dass mir am Ende nur neue Beiträge angezeigt werden, die beobachtet werden? Aktuell werden ja ALLE ungelesenen Beiträge gezählt.
 
Ich hoffe es geht so mit der Übersichtlichkeit. Ich könnte auch ein Screenshot machen.

Tabelle: post
Spalten: postid, threadid, parentid, username, userid, title, dateline, pagetext, allowsmilie, showsignature, ipaddress, iconid, visible, attach, infraction, reportthreadid, htmlstate

Tabelle: thread
Spalten: threadid, title, prefixid, firstpostid, lastpostid, lastpost, forumid, pollid, open, replycount, hiddencount, deletedcount, postusername, postuserid, lastposter, dateline, views, iconid, notes, visible, sticky, votenum, votetotal, attach, similar, taglist, lastposterid, keywords, postercount, panjo_listing_id

Tabelle: forum
Spalten: forumid, styleid, title, title_clean, description, description_clean, options, showprivate, displayorder, replycount, lastpost, lastposter, lastpostid, lastthread, lastthreadid, lasticonid, lastprefixid, threadcount, daysprune, newpostemail, newthreademail, parentid, parentlist, password, link, childlist, defaultsortfield, defaultsortorder, imageprefix, lastposterid

Tabelle: threadread
Spalten: userid, threadid, readtime

Tabelle: forumred
Spalten: userid, forumid, readtime

Tabelle: subscribethread
Spalten: subscribethreadid, userid, threadid, emailupdate, folderid, canview

Dann gäbe es noch eine weitere Tabelle womit ich zusätzlich prüfen könnte, ob es etwas neues in einem beachteten Forum gibt.

Tabelle: subscribeforum
Spalten: subscribeforumid, userid, forumid, emailupdate
 
Schon fast 1 Jahr um. :D

Edit:

Wäre es vielleicht Sinnvoller ein eigenes "Abo-System" zu programmieren?
 
Zuletzt bearbeitet:
Ich versuche gerade das vorhandene System zu verstehen und für meine Zwecke zu nutzen.

Was ich möchte?

Prüfen ob es in Abbonierten Themen neuen Beiträge gibt. Wenn ja, brauche ich a) die Anzahl der neuen Beiträge und b) halt die üblichen Infos wie Thread-Titel.

Schritt 1:
Ich lese aus der Datenbank (Tabelle "Abbonierte Themen") alle abbonierten Themen (ID's) aus.

Code:
1,5,20,300

Schritt 2:
Ich lese aus der Datenbank (Tabelle "Themen") mithilfe der ID's die gewünschten Informationen aus wie z.B. Themen-Titel.

Code:
1 -> PHP-Forum, Poster-Name, Timestamp
5 -> CSS-Forum, Poster-Name, Timestamp
20 -> Offtopic, Poster-Name, Timestamp
300 -> Downloads, Poster-Name, Timestamp

Schritt 3:
Tja... hier komme ich nicht weiter. :D

An dieser Stelle möchte ich prüfen ob es neue Beiträge gibt.
 
Zuletzt bearbeitet:
Ich bin meinem Ziel schon etwas näher gerückt.

Habe nun ein PlugIn geschrieben, welches jedem User "neue nicht gelesene" Beiträge pro Thread anzeigt. Gab es leider in der ganzen vBulletin-Szene nicht... Ist ein Eigenständiges System und ist z.B. nur beim "Foren/Forum als gelesen markieren" mit dem vBulletin Backend direkt verbunden, damit meine "Tabelle" mit "als gelesen" markiert wird.
 
Ich habe noch eine Frage. :)

Habe das mit den "JOIN's" leider noch nicht ganz verstanden.

SQL:
SELECT COUNT(post.postid) as unread FROM post AS post
INNER JOIN thread AS thread USING (threadid)
INNER JOIN forum AS forum USING (forumid)

In Worten:
1.) Zähle alle postid (als unread) von post (als post)
2.) Zähle in der selben Tabelle threadid?
3.) Zähle in der selben Tabelle forumid?

Die 1 ist richtig, aber 2 und 3?

Oder bedeutet es...

In Worten:
1.) Zähle alle postid (als unread) von post (als post)
2.) Wechsel in Tabelle "thread" und zähle dort "threadid"
3.) Wechsel in Tabelle "forum" und zähle dort "forumid"

Edit:

Hmm....

In Worten:
1.) Zähle alle "postid" (als unread) von post (als post)
2.) Wechsel in Tabelle "thread" und und verwende "threadid"
3.) Wechsel in Tabelle "forum" und und verwende "forumid"


?
 
Zuletzt bearbeitet:
Zurück