Archiv verlassen und diese Seite im Standarddesign anzeigen : [MySQL] Verbesserungsvorschläge und Frage zu Query mit JOINs
http://www.abload.de/img/db5jcq.png
Ich will eine Liste mit meinen News ausgeben lassen. Zuerst habe ich mir ein Array mit allen News von der DB geholt und alle News in einer Schleife ausgeben lassen. Dann habe ich in der Schleife zu jeder News überprüft ob Kommentare existieren und wenn ja die Anzahl ausgeben lassen.
Nun wollte ich aber alles in einer Abfrage machen, da dies bei vielen News sicherlich schneller geht und auch DB-schonender ist.
Folgendes SQL-Statement habe ich nun entwickelt, welches auch funktioniert:
"SELECT n.id, n.id_user, n.datum, n.titel, n.nachricht, n.kommentar, cat.name, COUNT(c.id_news) AS c_count
FROM _news n
LEFT JOIN _comments c ON n.id = c.id_news
GROUP BY n.id
ORDER BY n.datum DESC"
Wollte aber fragen, ob es da ne bessere Möglichkeit gibt.
Meine 2te Frage bezieht sich auf die Kategorien.
Da ich mehrere Kategorien pro News ermögliche, habe ich die Zwischentabelle _news_category erstellt.
Nun bekomme ich die Abfrage aber nicht mehr richtig hin. Die Anzahl der Kommentare stimmt nicht mehr und auch die Namen der Kategorien werden nicht richtig ausgelesen.
Wenn z.B. zwei Kategorien pro News vorliegen sollten beide ausgegeben werden. Das lässt sich wohl nur mit einer Unterabfrage lösen oder? Falls ja, wie genau?
Matrix316
2009-01-16, 14:40:28
Zu zwei: geht sowas net?
"SELECT n.id, n.id_user, n.datum, n.titel, n.nachricht, n.kommentar, cat.name, COUNT(c.id_news) AS c_count
FROM _news n
LEFT JOIN _comments c ON n.id = c.id_news INNER JOIN (bzw. left outer join, wenn manche news keine category hat) _news_category d on n.ID = d.id_news
GROUP BY n.id
ORDER BY n.datum DESC"
Da bekommste halt manche News mehrfach, wenn du mehrere news_category pro News hast.
Danke für den versuch aber das habe ich auch schon probiert.
Leider wird da nur eine Kategorie mit ausgegeben bzw. die selbe News wird mehrfach ausgegeben.
Das Problem liegt daran, dass manche News mehr als eine Kategorie besitzen können. Ich glaube mittlerweile dass das Problem nicht mit einem SQL-Statement zu lösen ist. Dazu müsste die Datenbank "String-Aggregation" unterstützen, was MySQL IMO aber nicht kann.
rotalever
2009-01-16, 16:58:47
Je nachdem was du machen willst, kann man bestimmt auch an anderer Stelle optimieren, als nur an der DB-Query.
Wenn das zum Beispiel eine Webseite ist, dann werden sich die News sicherlich nicht für jede DB-Abfrage ändern. Man kann sie also das Ergebnis der DB-Abfrage sehr leicht, z.B. in einer Datei oder noch besser in einem Memory-Cache zwischenspeichern.
Danke für den versuch aber das habe ich auch schon probiert.
Leider wird da nur eine Kategorie mit ausgegeben bzw. die selbe News wird mehrfach ausgegeben.
Das Problem liegt daran, dass manche News mehr als eine Kategorie besitzen können. Ich glaube mittlerweile dass das Problem nicht mit einem SQL-Statement zu lösen ist. Dazu müsste die Datenbank "String-Aggregation" unterstützen, was MySQL IMO aber nicht kann.
Was willst du denn genau haben bzw. wie soll dein Ergebnis aussehen? Wenn du die News pro Row ausgeben willst, bekommst du zwangsweise eine News mehrfach angezeigt, je nachdem wieviele Kategorien eben dazu existieren.
Du könntest vielleicht noch die Kategorien kommaspariert in eine Spalte schreiben, damit jede News nur einmal ausgegeben wird.
Was willst du denn genau haben bzw. wie soll dein Ergebnis aussehen? Wenn du die News pro Row ausgeben willst, bekommst du zwangsweise eine News mehrfach angezeigt, je nachdem wieviele Kategorien eben dazu existieren.
Du könntest vielleicht noch die Kategorien kommaspariert in eine Spalte schreiben, damit jede News nur einmal ausgegeben wird.
Ich möchte einfach jede News einmal ausgeben. Dazu die entsprechenden Kategorien der News.
Klar könnte ich die Kategorien in extra in der News-Tabelle noch hinterlegen. Allerdings ist dies unschön falls ich die Kategorien umbenenne etc.
daflow
2009-01-17, 10:31:09
Ich möchte einfach jede News einmal ausgeben. Dazu die entsprechenden Kategorien der News.
Klar könnte ich die Kategorien in extra in der News-Tabelle noch hinterlegen. Allerdings ist dies unschön falls ich die Kategorien umbenenne etc.
Und wie soll die Asugabe ausehen, wenn eine news nunmal mehrere Kategorien hat?
Wäre ja von der Logik vollkommen richtig wenn bei einer News mit 3 Kategorien auch 3 Datensätze für die News ausgegeben werden, oder wie soll das ganze formatiert sein?
Und wie soll die Asugabe ausehen, wenn eine news nunmal mehrere Kategorien hat?
Wäre ja von der Logik vollkommen richtig wenn bei einer News mit 3 Kategorien auch 3 Datensätze für die News ausgegeben werden, oder wie soll das ganze formatiert sein?
Die News soll einmal ausgegeben werden und alle 3 Kategorien bei ihr stehen.
Ich habe es jetzt über eine 2te Abfrage gelöst, die ein Array mit den Kategorien zu jeder News bereithält. Diese werden dann mit in der Schleife ausgegeben.
daflow
2009-01-17, 10:44:06
Die News soll einmal ausgegeben werden und alle 3 Kategorien bei ihr stehen.
Ich habe es jetzt über eine 2te Abfrage gelöst, die ein Array mit den Kategorien zu jeder News bereithält. Diese werden dann mit in der Schleife ausgegeben.
Ist imho auch die einzige Möglichkeit durch programmiertechnische Logik aussenrum zu realisieren, wenn du das ganze als "einen Datensatz" ausgegeben haben willst.
Matrix316
2009-01-17, 12:10:28
Die News soll einmal ausgegeben werden und alle 3 Kategorien bei ihr stehen.
Ich habe es jetzt über eine 2te Abfrage gelöst, die ein Array mit den Kategorien zu jeder News bereithält. Diese werden dann mit in der Schleife ausgegeben.
Wenn es pro News mehrere Kategorien gibt, bekommst du bei einer normalen Join abfrage nunmal dreimal die gleiche News, mit unterschiedlicher Kategorie. Dat is halt so.
Aber, du könntest vorher eine Abfrage machen, wie viele Kategorien die News hat und je nach dem fügst du neue Spalten hinzu. Oder du gibst der News Tabelle von vorneherein mehrere Spalten für Kategorien und du lässt es mit der eigenen Kategorie Tabelle. ;)
vBulletin®, Copyright ©2000-2024, Jelsoft Enterprises Ltd.