Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Lista tematów na forum
Forum PHP.pl > Forum > Bazy danych > MySQL
snapshot
Mam tabele topics i posts. Topics zawiera klucz obcy idPost z posts (są tam dane z "postu zakładającego temat"), a posts zawiera idTopics łączący z Topics. Wyciągam listę tematów z tytułem, datą założenia tematu, liczbą postów i ostatnią odpowiedzią:

  1. SELECT `t`.*, `p`.`dateCreate`, `p`.`idPost`, `p`.`idUser`, `u`.`login`, `u`.`idUser`, `u`.`isAdmin`, COUNT(p2.idPost) AS `posts`, MAX(p2.dateCreate) AS `dateReply`, `c`.`code` AS `countryCode`, `c`.`name` AS `countryName`
  2. FROM `topics` AS `t`
  3. INNER JOIN `posts` AS `p` ON t.idPost = p.idPost
  4. INNER JOIN `users` AS `u` ON p.idUser = u.idUser
  5. LEFT JOIN `posts` AS `p2` ON t.idTopic = p2.idTopic
  6. LEFT JOIN `countries` AS `c` ON u.userCountry = c.idCountry
  7. WHERE (t.idForum = 2) AND (p.idPost != p2.idPost)
  8. GROUP BY `t`.`idTopic`
  9. ORDER BY `dateReply` DESC



Nie wyświetlają mi się natomiast tematy nie mające odpowiedzi. Próbowałem kombinować z instrukcją warunkową IF(), ale do niczego nie doszedłem.
nieraczek
A po co w topics idPost ? Dane z postu zakładającego temat mogłeś dać do topics. I wtedy:
  1. LEFT JOIN `posts` AS `p` ON t.idTopic = p.idTopic
  2. INNER JOIN `users` AS `u` ON p.idUser = u.idUser
  3. LEFT JOIN `countries` AS `c` ON u.userCountry = c.idCountry


Ci pewnie nie chciało się dwa razy wstawiać identycznych kolumn w dwóch tabelach i zapewne dlatego tak zrobiłeś, ale już przy zwykłym wyszukaniu tematów, w których coś tam, coś tam - będziesz musiał łączyć dwie tabele i w ogóle zapytania się skomplikują.

Z drugiej strony nie trzeba dwa razy dawać takich samych kolumn dla dwóch tabel. Możesz spróbować tak:
  1. LEFT JOIN `posts` AS `p` ON (t.idTopic = p.idTopic AND t.idPost = p.idPost)
  2. INNER JOIN `users` AS `u` ON p.idUser = u.idUser
  3. LEFT JOIN `countries` AS `c` ON u.userCountry = c.idCountry
snapshot
Działa:

  1. SELECT
  2. `t`.*, `p`.`dateCreate`, `p`.`idPost`, `p`.`idUser`, `u`.`login`, `u`.`idUser`, `u`.`isAdmin`,
  3. COUNT(p2.idPost)-1 AS `posts`,
  4. IF(COUNT(p2.idPost)-1>0,MAX(p2.dateCreate),NULL) AS `dateReply`,
  5. `c`.`code` AS `countryCode`, `c`.`name` AS `countryName`
  6. FROM `topics` AS `t`
  7. INNER JOIN `posts` AS `p` ON t.idPost = p.idPost
  8. INNER JOIN `users` AS `u` ON p.idUser = u.idUser
  9. INNER JOIN `posts` AS `p2` ON t.idTopic = p2.idTopic
  10. LEFT JOIN `countries` AS `c` ON u.userCountry = c.idCountry
  11. WHERE (t.idForum = 2)
  12. GROUP BY `t`.`idTopic`
  13. ORDER BY MAX(p2.dateCreate) DESC


Mam tylko pytanie, czy wywoływanie po 2 razy MAX i COUNT jest dobre, czy jednak da się to zrobić optymalniej?
erix
Nie jestem pewien, ale czy by nie wystarczyło użycie samego aliasu zamiast drugiego count, ew. zmiennej?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.