Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Najmłodszy i najstarszy element zbioru
Forum PHP.pl > Forum > Przedszkole
Mephis
Witam.

Głowie się już od dłużej chwili nad rozwiązaniem raczej banalnej rzeczy.

Mam następujące tabele:
  1. -- Struktura tabeli dla tabeli `test_grupa_zbiorow`
  2. CREATE TABLE `test_grupa_zbiorow` (
  3. `id_grupy` int(11) NOT NULL
  4. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  5.  
  6. -- Zrzut danych tabeli `test_grupa_zbiorow`
  7. INSERT INTO `test_grupa_zbiorow` (`id_grupy`) VALUES
  8. (1),
  9. (2);
  10.  
  11.  
  12. -- Struktura tabeli dla tabeli `test_zbiory`
  13. CREATE TABLE `test_zbiory` (
  14. `zbior_id` int(11) NOT NULL,
  15. `grupa` int(11) NOT NULL,
  16. `nazwa` varchar(23) NOT NULL
  17. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  18.  
  19. -- Zrzut danych tabeli `test_zbiory`
  20. INSERT INTO `test_zbiory` (`zbior_id`, `grupa`, `nazwa`) VALUES
  21. (1, 1, 'zbior1'),
  22. (2, 1, 'zbior2'),
  23. (3, 1, 'zbior3'),
  24. (4, 2, 'zbior4'),
  25. (5, 2, 'zbior5');
  26.  
  27. -- Struktura tabeli dla tabeli `test_elementy`
  28. CREATE TABLE `test_elementy` (
  29. `elem_id` int(11) NOT NULL,
  30. `zbior` int(11) NOT NULL,
  31. `data_dodania` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  32. `nazwa` varchar(32) NOT NULL
  33. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  34.  
  35. -- Zrzut danych tabeli `test_elementy`
  36. INSERT INTO `test_elementy` (`elem_id`, `zbior`, `data_dodania`, `nazwa`) VALUES
  37. (1, 1, '2016-02-09 01:07:12', 'elem1'),
  38. (2, 1, '2016-02-09 04:12:11', 'elem2'),
  39. (3, 1, '2016-02-08 07:00:00', 'elem3'),
  40. (4, 2, '2016-02-24 05:00:00', 'elem4'),
  41. (5, 2, '2016-02-07 00:13:30', 'elem5'),
  42. (6, 3, '2016-02-19 00:00:00', 'elem6'),
  43. (7, 3, '2016-02-12 00:00:00', 'elem7'),
  44. (8, 3, '2016-02-13 00:00:00', 'elem8');


Jest to grupa zbiorów, jej zbiory i elementy tychże zbiorów.
Chciałbym wyświetlić teraz w jednym wierszu:
- identyfikator zbioru
- najwcześniej dodany element
- najpóźniej dodany element
Zbiór należący do pewnej grupy zbiorów.

Naskrobałem coś w tym rodzaju, ale rzecz jasna nie działa:
  1. SELECT
  2.  
  3. `tz`.`zbior_id` AS `identyfikator zbioru`,
  4. `te_m`.`elem_id` AS `najmlodszy element`,
  5. `te_s`.`elem_id` AS `najstarszy element`
  6.  
  7. FROM `test_zbiory` `tz`
  8. LEFT JOIN (SELECT * FROM `test_elementy` ORDER BY `data_dodania` ASC LIMIT 1) `te_m` ON(`te_m`.`zbior` = `tz`.`zbior_id`)
  9. LEFT JOIN (SELECT * FROM `test_elementy` ORDER BY `data_dodania` DESC LIMIT 1) `te_s` ON(`te_s`.`zbior` = `tz`.`zbior_id`)
  10.  
  11. WHERE `tz`.`grupa` = 1
  12. GROUP BY `tz`.`zbior_id`


Otrzymuję taki wynik:
identyfikator zbioru | najmlodszy element | najstarszy element
1 | NULL | NULL
2 | 5 | 4
3 | NULL | NULL

Dlaczego dzieje się cokolwiek w przypadku zbioru nr 2?
W jaki sposób wyświetlić pożądany wynik?
ilies
Spróbuj tego
  1. SELECT `tz`.`zbior_id` AS `identyfikator zbioru`,
  2. min(`te`.`elem_id`) AS `najmlodszy element`,
  3. max(`te`.`elem_id`) AS `najstarszy element`
  4. FROM `test_zbiory` `tz`
  5. LEFT JOIN `test_elementy` `te` ON `te_m`.`zbior` = `tz`.`zbior_id`
  6. WHERE `tz`.`grupa` = 1
  7. GROUP BY `tz`.`zbior_id


Nic nie dzieje się ze zbirem 2, wyświetlasz id zbiorów, a masz przypisany zbiór 1 do trzech pierwszych rekordów, czyli na pewno będziesz mieć trzy wyniki, gdzie w pierwszej kolumnie kolejno będą 1 2 3
Mephis
Niestety, powyższe zapytanie wybiera najmniejszy i największy element zbioru. Mi chodzi o najmłodszy i najstarszy, czyli wybieranie elementów zbioru z grupy, wedug "daty ich dodania". Owa data tak na prawdę się będzie zmieniać, dlatego nie może być to największy i najmniejszy id zbioru z grupy.
ilies
  1. declare @grupaNr int;
  2. SET @grupaNr = 1;
  3. SELECT
  4. `tz`.`zbior_id` AS `identyfikator zbioru`,
  5. `te_m`.`elem_id` AS `najmlodszy element`,
  6.  
  7. `te_s`.`elem_id` AS `najstarszy element`,
  8. max(`te_s`.`data_dodania`) AS date_max
  9. FROM `test_zbiory` `tz`
  10. LEFT JOIN `test_elementy` `te_m` ON (`te_m`.`zbior` = `tz`.`zbior_id`)
  11. LEFT JOIN `test_elementy` `te_s` ON (`te_s`.`zbior` = `tz`.`zbior_id`)
  12. WHERE `tz`.`grupa` = @grupaNr
  13. AND `te_s`.`elem_id` = (SELECT max(te.data_dodania) FROM test_elemnty te LEFT JOIN test_zbiory tz ON te.zbior = tz.zbior_id WHERE tz.grupa = @grupaNr)
  14. AND `te_m`.`elem_id` = (SELECT min(te.data_dodania) FROM test_elemnty te LEFT JOIN test_zbiory tz ON te.zbior = tz.zbior_id WHERE tz.grupa = @grupaNr)
  15. GROUP BY `tz`.`zbior_id`

Nie jestem pewien co do deklarowania zmiennych, pod MsSQL nie robiłem tego (poniżej linki gdzie znalazłem), zawsze zamiast tego możesz wszędzie wpisać 1, przydatne linki:
http://stackoverflow.com/questions/1175478...riable-in-mysql
http://www.techonthenet.com/mysql/declare_vars.php
http://stackoverflow.com/questions/9617453...th-where-clause
Mephis
Niestety, zapytanie zwraca pusty wynik.
Czy ktoś ma jakieś pomysły?

Naskrobałem coś takiego:
  1. SELECT * FROM `test_elementy` WHERE `data_dodania` IN (SELECT max(`data_dodania`) FROM `test_elementy` GROUP BY `zbior`)

I otrzymuję wynik taki jaki chcę... Ale czy istnieje jakieś bardziej profesjonalne wykonanie?
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.