Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Ostatni wpis (z grup i subgrup), Ostatni wpis z grupy i subgrupy
Mephis
post 18.03.2017, 19:47:12
Post #1





Grupa: Zarejestrowani
Postów: 94
Pomógł: 1
Dołączył: 16.12.2012

Ostrzeżenie: (0%)
-----


Witam.

Posiadam coś takiego jak:
- grupy
  • id
  • nazwa

- debaty (należą do grup)
  • id
  • id_grupy
  • nazwa

- wpisy (należą do debat)
  • id
  • id_debaty
  • treść
  • data


Poniżej umieszczam zrzut bazy danych:
  1. CREATE DATABASE IF NOT EXISTS `test_lastentry` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
  2. USE `test_lastentry`;
  3.  
  4. CREATE TABLE `groups` (
  5. `group_id` tinyint(1) UNSIGNED NOT NULL,
  6. `name` varchar(65) NOT NULL
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  8.  
  9. CREATE TABLE `debates` (
  10. `debate_id` smallint(2) UNSIGNED NOT NULL,
  11. `group_fk` tinyint(1) UNSIGNED NOT NULL,
  12. `name` varchar(65) NOT NULL
  13. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  14.  
  15. CREATE TABLE `entries` (
  16. `entry_id` smallint(2) UNSIGNED NOT NULL,
  17. `debate_fk` smallint(2) UNSIGNED NOT NULL,
  18. `content` varchar(65) NOT NULL,
  19. `date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
  20. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  21.  
  22. INSERT INTO `groups` (`group_id`, `name`) VALUES
  23. (1, 'group_one'),
  24. (2, 'group_second'),
  25. (3, 'group_third');
  26.  
  27. INSERT INTO `debates` (`debate_id`, `group_fk`, `name`) VALUES
  28. (1, 1, 'debate 1 for group 1'),
  29. (2, 2, 'debate 1 for group 2'),
  30. (3, 2, 'debate 2 for group 2'),
  31. (4, 2, 'debate 3 for group 2'),
  32. (5, 3, 'debate 1 for group 3'),
  33. (6, 3, 'debate 2 for group 3');
  34.  
  35. INSERT INTO `entries` (`entry_id`, `debate_fk`, `content`, `date`) VALUES
  36. (1, 1, 'entry 1 for debate 1', '2017-03-12 03:12:23'),
  37. (2, 1, 'entry 2 for debate 1', '2017-03-13 03:15:18'),
  38. (3, 2, 'entry 1 for debate 2', '2017-03-13 06:40:20'),
  39. (4, 2, 'entry 2 for debate 2', '2017-03-14 09:15:24'),
  40. (5, 3, 'entry 1 for debate 3', '2017-03-12 02:12:05'),
  41. (6, 3, 'entry 2 for debate 3', '2017-03-13 13:47:52'),
  42. (7, 3, 'entry 3 for debate 3', '2017-03-15 14:15:15'),
  43. (8, 4, 'entry 1 for debate 4', '2017-03-15 14:15:15'),
  44. (9, 5, 'entry 1 for debate 5', '2017-03-11 08:11:39'),
  45. (10, 5, 'entry 2 for debate 5', '2017-03-12 16:22:18'),
  46. (11, 6, 'entry 1 for debate 6', '2017-03-14 09:15:24');
  47.  
  48. ALTER TABLE `groups`
  49. ADD PRIMARY KEY (`group_id`);
  50. ALTER TABLE `debates`
  51. ADD PRIMARY KEY (`debate_id`);
  52. ALTER TABLE `entries`
  53. ADD PRIMARY KEY (`entry_id`);
  54.  
  55. ALTER TABLE `groups`
  56. MODIFY `group_id` tinyint(1) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
  57. ALTER TABLE `debates`
  58. MODIFY `debate_id` smallint(2) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13;
  59. ALTER TABLE `entries`
  60. MODIFY `entry_id` smallint(2) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;


A tutaj zobrazowane dane:

GROUP - grupa
D - "debates" - debaty
E - "entries" - wpisy
last (X) - ostatni wpis w debacie (o czasie X)


Najpierw sprawa jest w miarę prosta.
Utworzyłem sobie listę "debat" wraz z danymi dot. ostatniego wpisu i wygląda to następująco:
  1. SELECT
  2. `d`.`debate_id`,
  3. `d`.`name`,
  4. `last_e`.*
  5. FROM `debates` AS `d`
  6. LEFT JOIN (
  7. SELECT
  8. `e`.`debate_fk`,
  9. `e`.`entry_id`,
  10. `e`.`content`,
  11. `e`.`date`
  12. FROM `entries` AS `e`
  13. INNER JOIN (
  14. SELECT
  15. `debate_fk`,
  16. MAX(`date`) AS `date`
  17. FROM `entries`
  18. GROUP BY `debate_fk`
  19. ) AS `last_e_pd` ON (
  20. (`last_e_pd`.`debate_fk` = `e`.`debate_fk`)
  21. AND (`last_e_pd`.`date` = `e`.`date`)
  22. )
  23. ) AS `last_e` ON (`last_e`.`debate_fk` = `d`.`debate_id`)

Dałoby się jakąś to uprościć? Jakieś uwagi?

Cóż chciałbym osiągnąć? Chciałbym pobrać listę grup (a nie dabat) wraz z danymi dot. ostatniego wpisu (i dot. debaty do której wpis ten należy) w grupie...
Czyli identyfikator i nazwę grupy, identyfikator, treść i datę ostatniego wpisu oraz identyfikator i nazwa debaty.

Przy liście z "debatami" sprawa była prosta o tyle, że pobierałem najwyższą wartość (date) i grupowałem wg. id debaty - tutaj otrzymywałem wymagany wynik.
Jeśli chciałbym do wpisów dołączyć tabelę debat (aby otrzymać z nich fk grupy), to grupując wg fk grupy nie otrzymam pożądanych wyników, ponieważ zgadzać będzie się id grupy, data ostatniego wpisu, ale id debaty zostanie wzięte pierwsze z brzegu (i nie będzie zgodny z oczekiwaniami... eh, gdyby tylko ten "MAX" wybierał cały wiersz a nie tylko komórkę).
Posiadając id grupy i datę ostatniego wpisu, nie mogę do tego dołączyć wpisów (co mógłbym zrobić tylko na podstawie daty), ponieważ jeśli wpisy z różnych debat będą mieć identyczny czas (mało prawdopodobne, ale jednak), to wynik będzie nieprawidłowy.

Czy ktoś borykał się z podobnym problemem? Miałby ktoś jakieś pomysły?

Proszę o pomoc.

Ten post edytował Mephis 18.03.2017, 19:52:50
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 03:39