2 tabellen überprüfen
Markus
- datenbank
hallo!
folgende zeilen nutze ich, um die top 20 der gästebucheinträge meiner mitglieder zu suchen:
$r = database("SELECT ownerid FROM " . $dbpref . "guestbooks");
while ($u = mysql_fetch_assoc($r)) {
$ownerid = $u['ownerid'];
$temp[$ownerid]++;
}
arsort($temp);
echo " <td valign="top">\n";
$i = 0;
foreach ($temp as $key => $value) {
if ($i > 19) break;
$r = database("SELECT * FROM " . $dbpref . "user WHERE userstatus > 0 AND id = $key");
$u = mysql_fetch_assoc($r);
...
geht das auch einfacher mit einer verknüpfung der abfrage? wenn ja, wie? ich habe da etwas gelesen, aber nicht wirklich verstanden. danke!
Halihallo Markus
foreach ($temp as $key => $value) {
if ($i > 19) break;
müsste hier nicht if ($value > 19) break; stehen?
$r = database("SELECT * FROM " . $dbpref . "user WHERE userstatus > 0 AND id = $key");
$u = mysql_fetch_assoc($r);
geht das auch einfacher mit einer verknüpfung der abfrage? wenn ja, wie? ich habe da etwas gelesen, aber nicht wirklich verstanden. danke!
Ja, du bräuchtest einen Subselect (gibt's aber z. B. in mysql nicht). Falls subselects
von deinem RDBMS nicht unterstützt werden, geht's IMHO nur über zwei/mehrere Queries.
Viele Grüsse
Philipp
hallo philipp,
Halihallo Markus
müsste hier nicht if ($value > 19) break; stehen?
ups, am ende der foreach steht noch folgendes:
$i++;
}
damit ist es dann ok...
Ja, du bräuchtest einen Subselect (gibt's aber z. B. in mysql nicht). Falls subselects
von deinem RDBMS nicht unterstützt werden, geht's IMHO nur über zwei/mehrere Queries.
bahnhof? chinesisch? also ist die lösung so schon ok?
Viele Grüsse
Philipp
gruß
markus
Halihallo Markus
müsste hier nicht if ($value > 19) break; stehen?
ups, am ende der foreach steht noch folgendes:
$i++;
}
Stimmt. Obwohl die Lösung über die DB besser (im Sinne von performance) ist.
Ja, du bräuchtest einen Subselect (gibt's aber z. B. in mysql nicht). Falls subselects
von deinem RDBMS nicht unterstützt werden, geht's IMHO nur über zwei/mehrere Queries.bahnhof? chinesisch? also ist die lösung so schon ok?
Das folgerte ich fälschlicherweise, ja. Deine Lösung ist OK, jedoch mit dem Query meines
zweiten Postings zu verbessern (das Sortieren und Einschränken der Ergebnismenge
steigert die Performance). Ich ging fälschlicherweise davon aus, dass du auch die
einzelnen Daten der Beiträge benötigst, dies ginge nicht ohne mehrere Queries oder
Subselects (welche nicht in jedem DB implementiert sind). Wenn du nur die Top-20 Poster
ausgeben willst, sollte der Query vom zweiten Posting funktionieren (unten die
korrigierte Version).
SELECT u.*, COUNT(gb.ownerid) AS 'count'
FROM
guestbook AS gb,
user as u
WHERE
gb.ownerid=u.id
GROUP BY
gb.ownerid
ORDER BY 'count' DESC
LIMIT 0, 20
Du machst einen GROUP BY ownerid/id und zählst die Anzahl Postings jedes users. Mit dem
ORDER BY sortierst du diese und mit dem LIMIT 0, 20 selektierst du die ersten 20
Einträge (das sind dann eben diejenigen, welche am meisten gepostet haben).
Viele Grüsse
Philipp
Du machst einen GROUP BY ownerid/id und zählst die Anzahl Postings jedes users. Mit dem
ORDER BY sortierst du diese und mit dem LIMIT 0, 20 selektierst du die ersten 20
Einträge (das sind dann eben diejenigen, welche am meisten gepostet haben).Viele Grüsse
Philipp
hallo philipp,
vielen dank!
ich denke, dass ich das mit deiner erklärung verstehen werde...
gruß
markus
SELECT u.*, COUNT(gb.ownerid) AS 'count'
FROM
guestbook AS gb,
user as u
WHERE
gb.ownerid=u.id
GROUP BY
gb.ownerid
ORDER BY 'count' DESC
LIMIT 0, 20
das klappt prima, aber ich würde auch gerne die ohne einträge noch hinten dran listen. geht das auch?
user a - 15 einträge
user b - 12 einträge
user c - 3 einträge
user d - 0 einträge
gruß
markus
Halihallo Markus
das klappt prima, aber ich würde auch gerne die ohne einträge noch hinten dran listen. geht das auch?
Nicht in einem Query (ich hoffe, dass ich nicht schon wieder einen Denkfehler mache...),
obwohl ich glaube, dass dein Vorhaben auch keinen Sinn ergibt. Du möchtest die Top-20
Poster ausgeben, was haben da Poster mit 0 Postings zu suchen?
Um noch alle Poster mit 0 Beiträgen auszugeben, benutze:
SELECT u.*
FROM
guestbook AS gb
LEFT OUTER JOIN user as u ON u.id=gb.ownerid
WHERE
gb.ownerid = NULL
dies ist meiner Meinung nach die schnellste Möglichkeit, lasse mich jedoch gerne
korrigieren (bei einem Fehler im Query sowieso). Zur Implementierung: Einfach den zuvor
geposteten Query ausführen, die Results anzeigen und dann den oben beschriebenen (und
wieder ausgeben).
Zum Query: Alle Poster auszugeben, die noch keinen Beitrag geschrieben haben ist
gleichbedeutend mit der Aussage: Alle Poster ausgeben, welche _nicht_ mit mindestens
einem Eintrag aus der gb - Tabelle verknüpft werden können. Dies kann man über einen
LEFT OUTER JOIN erreichen, welcher eben die nicht in der anderen Tabelle existierenden
Felder (bezogen auf die Kondition u.id=gb.ownerid) mit dem Wert NULL füllt. Auf diesen
kannst du in dem WHERE (WHERE gb.ownerid=NULL) prüfen und bekommst so alle User zurück,
welche noch keinen Beitrag geschrieben haben.
Viele Grüsse
Philipp
Nicht in einem Query (ich hoffe, dass ich nicht schon wieder einen Denkfehler mache...),
obwohl ich glaube, dass dein Vorhaben auch keinen Sinn ergibt. Du möchtest die Top-20
Poster ausgeben, was haben da Poster mit 0 Postings zu suchen?
Um noch alle Poster mit 0 Beiträgen auszugeben, benutze:
es geht darum, dass ich zum einen die top20 anzeige (ohne die, die noch keinen eintrag haben) und dann über eine mitgliedergalerie, die nach verschiedenen kriterien neu sortiert werden kann, will ich immer alle mitglieder anzeigen lassen. daher sollen auch die mit 0 einträgen gezeigt werden...
das problem ist jetzt, es müsste beides in einen query, weil ich immer 10 pro seite zeige und den limit daher auf $start,10 setze... das gelingt mir mit meinem verständnis aber nicht bei 2 queries...
gruß
markus
Halihallo Markus
das problem ist jetzt, es müsste beides in einen query, weil ich immer 10 pro seite zeige und den limit daher auf $start,10 setze... das gelingt mir mit meinem verständnis aber nicht bei 2 queries...
Stimmt. Wenn du nach wie vor die Daten aus den Gästebucheinträgen nicht brauchst, kannst
du folgenden Query benutzen:
SELECT
u.*,
COUNT(gb.ownerid) AS count
FROM
user AS u
LEFT OUTER JOIN guestbook AS gb ON gb.ownerid=u.id
ORDER BY count
GROUP BY gb.ownerid
LIMIT $start, 10
Damit erhälst du dann etwa folgendes:
id name count
1 n1 3
2 n2 2
3 n3 0
ist es das, wonach du suchst?
Der LEFT OUTER JOIN (falls du den noch nicht kennst), brauchst du, um auch User
anzuzeigen, welche gar nicht mit der Guestbook-Tabelle gejoined werden können, da sie
gar keine Beiträge geschrieben haben. Alle Felder von Guestbook werden in dem Falle mit
NULL gefüllt, was bei einem COUNT(gb.ownerid) zu einer '0' führt (also keine Beiträge).
Viele Grüsse
Philipp
hallo philipp,
erstmla vielen dank für deine bemühungen, aber so ganz klappt dein query nicht.
SELECT
u.*,
COUNT(gb.ownerid) AS count
FROM
user AS u
LEFT OUTER JOIN guestbook AS gb ON gb.ownerid=u.id
ORDER BY count
GROUP BY gb.ownerid
LIMIT $start, 10Damit erhälst du dann etwa folgendes:
id name count
1 n1 3
2 n2 2
3 n3 0
das wäre die perfekte lösung, ja... ;-)
ich habe den query jetzt etwas verändert, aber es geht noch immer nicht:
SELECT u.*, COUNT(gb.ownerid) AS 'count' FROM " . $dbpref . "guestbooks AS gb, " . $dbpref . "user AS u LEFT OUTER JOIN guestbooks AS gb ON gb.ownerid=u.id ORDER BY 'count' GROUP BY gb.ownerid LIMIT $start, 10
es erscheint der fehler:
Keine eindeutige(n) Tabelle/Alias: 'gb'
Halihallo Markus
erstmla vielen dank für deine bemühungen, aber so ganz klappt dein query nicht.
Der einzige Fehler, den ich in meinem Query gesehen habe ist, dass ich den ORDER BY vor
dem GROUP BY hatte (was zu einem Fehler führt). ;)
ich habe den query jetzt etwas verändert, aber es geht noch immer nicht:
Eben wegen deinen Veränderungen, schätze ich ;)
SELECT u.*, COUNT(gb.ownerid) AS 'count' FROM " . $dbpref . "guestbooks AS gb, " . $dbpref . "user AS u LEFT OUTER JOIN guestbooks AS gb ON gb.ownerid=u.id ORDER BY 'count' GROUP BY gb.ownerid LIMIT $start, 10
es erscheint der fehler:
Keine eindeutige(n) Tabelle/Alias: 'gb'
schau dir doch deinen Query mal an. Du hast zweimal guestbook in dem FROM-Kontainer und
beide hast du mit dem Alias gb verknüpft; ist klar, dass mysql dann reagiert...
Das erste FROM guestbooks AS gb brauchst du nicht, ich hatte da ja den LEFT OUTER JOIN
für die Tabelle guestbook eingeführt.
Viele Grüsse
Philipp
Halihallo Markus
[...]
Ich hab zu weit gedacht; dachte fälschlicherweise, dass du auch die Gästebucheinträge
brauchst. Hier der Query [bin grad gestresst, kann nachher noch erläutern, falls erwünscht]
SELECT u.*, COUNT(*) AS 'count'
FROM
guestbook AS gb,
user as u
WHERE
db.ownerid=u.id
GROUP BY
db.ownerid
ORDER BY 'count'
LIMIT 0, 20
Viele Grüsse
Philipp