Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Ostatni wpis (z grup i subgrup), Ostatni wpis z grupy i subgrupy
Mephis
post
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:
(IMG:https://zapodaj.net/images/d9263e25416b7.png)
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
 
Start new topic
Odpowiedzi (1 - 2)
javafxdev
post
Post #2





Grupa: Zarejestrowani
Postów: 95
Pomógł: 7
Dołączył: 27.10.2015

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


"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..."
a potem:
"...ponieważ jeśli wpisy z różnych debat będą mieć identyczny czas (mało prawdopodobne, ale jednak), to wynik będzie nieprawidłowy..."

to co chciałbyś uzyskać jak jednak ten przypadek się zdarzy? listę dot. ostatnich wpisów czy jak niby to by miało działać?

Go to the top of the page
+Quote Post
Mephis
post
Post #3





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

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


W tym pierwszym zapytaniu otrzymuję listę debat i połączone z nimi ostatnie wpisy:
(IMG:https://zapodaj.net/images/8bb0a313f613a.png)

Chcę uzyskać listę grup i połączone z nimi ostatnie wpisy (i debaty), czyli te wiersze:
  1. SELECT
  2. `g`.*,
  3. `d`.`debate_id`,
  4. `d`.`name`,
  5. `last_e`.`debate_fk`,
  6. `last_e`.`entry_id`,
  7. `last_e`.`content`,
  8. `last_e`.`date`
  9. FROM `groups` AS `g`
  10. LEFT JOIN `debates` AS `d` ON (`d`.`group_fk` = `g`.`group_id`)
  11. LEFT JOIN (
  12. SELECT
  13. `e`.`debate_fk`,
  14. `e`.`entry_id`,
  15. `e`.`content`,
  16. `e`.`date`
  17. FROM `entries` AS `e`
  18. INNER JOIN (
  19. SELECT
  20. `debate_fk`,
  21. MAX(`date`) AS `date`
  22. FROM `entries`
  23. GROUP BY `debate_fk`
  24. ) AS `last_e_pd` ON (
  25. (`last_e_pd`.`debate_fk` = `e`.`debate_fk`)
  26. AND (`last_e_pd`.`date` = `e`.`date`)
  27. )
  28. ) AS `last_e` ON (`last_e`.`debate_fk` = `d`.`debate_id`)

(IMG:https://zapodaj.net/images/b8b009e5b5390.png)

Lecz, w przypadku, kiedy chciałbym pogrupować wg. grupy i pobrać najwyższą wartość z daty (tak, jak robię to w przypadku listy debat):
  1. SELECT
  2. `g`.*,
  3. `d`.`debate_id`,
  4. `d`.`name`,
  5. `last_e`.`debate_fk`,
  6. `last_e`.`entry_id`,
  7. `last_e`.`content`,
  8. MAX(`last_e`.`date`) AS `date`
  9. FROM `groups` AS `g`
  10. LEFT JOIN `debates` AS `d` ON (`d`.`group_fk` = `g`.`group_id`)
  11. LEFT JOIN (
  12. SELECT
  13. `e`.`debate_fk`,
  14. `e`.`entry_id`,
  15. `e`.`content`,
  16. `e`.`date`
  17. FROM `entries` AS `e`
  18. INNER JOIN (
  19. SELECT
  20. `debate_fk`,
  21. MAX(`date`) AS `date`
  22. FROM `entries`
  23. GROUP BY `debate_fk`
  24. ) AS `last_e_pd` ON (
  25. (`last_e_pd`.`debate_fk` = `e`.`debate_fk`)
  26. AND (`last_e_pd`.`date` = `e`.`date`)
  27. )
  28. ) AS `last_e` ON (`last_e`.`debate_fk` = `d`.`debate_id`)
  29. GROUP BY `g`.`group_id`

(IMG:https://zapodaj.net/images/7f378f46efbfe.png)
...otrzymuję nieprawidłowe wyniki.
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 24.08.2025 - 23:18