Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL]Produkty z kategorii i podkategorii
Forum PHP.pl > Forum > Przedszkole
arturpiotrowski
Witam jestem tu nowy i dopiero zaczynam swoją przygodę z PHP, HTML ogarniam już chyba całkiem dobrze więc pora wejść na wyższy poziom i pomyśleć o PHP/MySQL

Mam przykładową bazę ze strukturą tabel
  1. CREATE TABLE `kategorie` (
  2. `kategoria_id` smallint(5) UNSIGNED NOT NULL,
  3. `rodzic_id` smallint(5) UNSIGNED NOT NULL DEFAULT '1',
  4. `kategoria` varchar(60) NOT NULL
  5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  6. INSERT INTO `kategorie` (`kategoria_id`, `rodzic_id`, `kategoria`) VALUES
  7. (1, 0, 'Produkty'),
  8. (2, 1, 'AGD'),
  9. (3, 1, 'RTV'),
  10. (4, 2, 'Miksery'),
  11. (5, 2, 'Tostery'),
  12. (6, 3, 'Telewizory'),
  13. (7, 3, 'Kina domowe');
  14. CREATE TABLE `kat_produkty` (
  15. `id` int(10) UNSIGNED NOT NULL,
  16. `kategoria_id` smallint(5) UNSIGNED NOT NULL,
  17. `produkt_id` int(10) UNSIGNED NOT NULL
  18. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  19. INSERT INTO `kategorie_produkty` (`id`, `kategoria_id`, `produkt_id`) VALUES
  20. (1, 4, 4),
  21. (2, 5, 5),
  22. (3, 6, 1);
  23. (4, 6, 2);
  24. CREATE TABLE `produkty` (
  25. `produkt_id` int(10) UNSIGNED NOT NULL,
  26. `nazwa` varchar(255) NOT NULL
  27. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  28. INSERT INTO `produkty` (`produkt_id`, `nazwa`) VALUES
  29. (1, 'Produkt 1'),
  30. (2, 'Produkt 2'),
  31. (3, 'Produkt 3'),
  32. (4, 'Produkt 4'),
  33. (5, 'Produkt 5');

Jak powinno wyglądać zapytanie abym mógł wyciągnąć z tabeli produktów wszystkie produkty z kategorii "AGD" i podkategorii dla których id rodzica to id kategorii "AGD"?
Niree
  1. CREATE TABLE `kat_produkty` (
  2. `id` int(10) UNSIGNED NOT NULL,
  3. `kategoria_id` smallint(5) UNSIGNED NOT NULL,
  4. `produkt_id` int(10) UNSIGNED NOT NULL
  5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  6. INSERT INTO `kategorie_produkty` (`id`, `kategoria_id`, `produkt_id`) VALUES
  7. (1, 4, 4),
  8. (2, 5, 5),
  9. (3, 6, 1);
  10. (4, 6, 2);
  11. CREATE TABLE `produkty` (
  12. `produkt_id` int(10) UNSIGNED NOT NULL,
  13. `nazwa` varchar(255) NOT NULL
  14. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  15. INSERT INTO `produkty` (`produkt_id`, `nazwa`) VALUES
  16. (1, 'Produkt 1'),
  17. (2, 'Produkt 2'),
  18. (3, 'Produkt 3'),
  19. (4, 'Produkt 4'),
  20. (5, 'Produkt 5');


Nie lepiej zrobić jedną tabelę? Później będziesz za dużo miał mieszania wśród tabel.
produkty:

id | kategoria | ewentualna podkategoria | nazwa produktu

Później tylko wyciągasz dane z tabeli "produkty":

  1. SELECT * FROM `produkty` WHERE `kategoria` = '2' or `subkategoria` = '1' ORDER BY id
arturpiotrowski
Rozumiem że myślisz o wrzuceniu kategorii i podkategorii do tabeli produkty? Pewnie by było to i dobre rozwiązanie gdyby nie fakt że 1 produkt może należeć do wielu kategorii...

to może inaczej jest taka struktura menu kategorii:
  1. Produkty spożywcze - (zawiera 2 produkty)
  2. - Nabiał - (3 produkty)
  3. - Pieczywo - (6 produktów)
  4. Produkty RTV AGD (zawiera 1 produkt)
  5. - AGD - (zawiera 2 produkty)
  6. -- Zmywarki - (zawiera 3 produkty)
  7. --- Do zabudowy - (zawiera 4 produkty)


przeglądając zawartość kategorii "Produkty RTV AGD" potrzebuje wyjąć wszystkie produkty co są w kategoriach "głebiej" i w tej "Produkty RTV AGD" czyli razem 10 produktów, jak powinno wyglądać zaputanie które zwróci mi tablicę z tymi produktami?
rad11
Sprobuj to:
  1.  
  2. Select p.* from kat_produkty kp left join kategorie k on kp.kategoria_id = k.kategoria_id left join produkty p on kp.produkt_id = p.produkt_id Where k.kategoria_id = 2 and k.rodzic_id = 2
  3.  


pisane z telefonu moga byc jakies bledy.

Natomiast jesli chcesz zrobić to rekursywnie to musisz uzyc raczej PHP i MySQL do tego.
arturpiotrowski
Czy to co dopisałem wymaga aby zrobić to rekursywnie?
Jeśli tak to czy mogę prosić o podpowiedz jak to rozwiązać rekursywnie?
rad11
Tak do tego będziesz musiał użyć funkcji rekursywnej zdanie klucz do google to "php mysql recursive categories"
nospor
Zacznij od przygotowania poprawnej struktury drzewiastej a zadne durne zasobozerne rekurencje ci nie beda potrzebe.

google: drzewka IP
Niree
  1. Rozumiem że myślisz o wrzuceniu kategorii i podkategorii do tabeli produkty? Pewnie by było to i dobre rozwiązanie gdyby nie fakt że 1 produkt może należeć do wielu kategorii...


No przecież możesz dodać wiele kategorii.

ID | kategoria | Subkategoria | produkt

Przykład:
1 | 1,2,3 | 1,2 | Nazwa produktu.

Przy wyświetlaniu patrzysz, czy w danej kolumnie jest np. kategoria 1 i wyświetlasz. To są podstawy tongue.gif
Póki co Twoja baza wymaga, żeby dla każdego produktu w danej kategorii był nowy wpis. Po co?
Jest produkt i ma przydzielone konkretne kategorie.
nospor
Cytat
Przy wyświetlaniu patrzysz, czy w danej kolumnie jest np. kategoria 1 i wyświetlasz. To są podstawy

facepalmxd.gif

NIree ja cie najmocniej przepraszam ale ty ostatnio jak cos palniesz to az strach. I jeszcze wyjezdzasz ze to sa podstawy.... Sam sie podksztalc troche w podstaw baz danych i ja sie poprawnie je projektuje bo to co teraz wygadujesz to herezje.
Niree
Cytat(nospor @ 6.12.2016, 21:38:21 ) *
facepalmxd.gif

NIree ja cie najmocniej przepraszam ale ty ostatnio jak cos palniesz to az strach. I jeszcze wyjezdzasz ze to sa podstawy.... Sam sie podksztalc troche w podstaw baz danych i ja sie poprawnie je projektuje bo to co teraz wygadujesz to herezje.


haha.gif

Nie jeden skrypt na tej zasadzie robiłem.
Nie widzę sensu rozdzielania tego. Tak samo jak np. system z podziałem na uprawnienia. Robiłbyś osobne kolumny do danego modułu, czy lepiej uprawnienia połączyć przecinkami, a później na stronie rozdzielać explode()?
nospor
Cytat
Robiłbyś osobne kolumny do danego modułu, czy lepiej uprawnienia połączyć przecinkami, a później na stronie
Lo matko.... jakie kolumny....

Cytat
Nie jeden skrypt na tej zasadzie robiłem.
To, ze robisz skrypty bez znajomosci podstaw baz danych, nie znaczy ze to jest dobrze i masz te "wiedze" wbijac innym.

NIe, zaproponowany przez ciebie model jest totalnie zly. Podejscie autora jest prawidlowe, procz rzecz jasna faktu, ze wybral zla strukture na drzewo.
Tak, tworzy sie wlasnie tabele wiazaca produkty z kategoriami i tak, dla kazdej pary produkt-kategoria tworzy sie kolejny rekord w bazie. Dzieki temu mozna robic wszelke niezbedne operacje na bardzo duzych bazach bardzo szybko.

Niree
Chyba przez Ciebie zacznę pić. arrowheadsmiley.png
nospor
Jesli miedzy kieliszkami bedziesz studiowal podstawy to tylko na zdrowie ci wyjdzie tongue.gif
arturpiotrowski
nospor, dziękuję znalazłem to: http://www.eioba.pl/a/3m/drzewa-w-php-i-mysql
Stworzenie tabeli ze strukturą drzewiastą to nie problem, dłużej mi się zejdzie zrozumienie tego jak to działa sad.gif
nospor
Bo wybrales calkiem trudna implementacje drzewa.

Ja ci podalem: drzewka IP
sa o wiele prostsze a robia co maja robic smile.gif
arturpiotrowski
nospor, a mógłbyś podrzucić jakiś link z prostszą implementacją? Najlepiej po polsku
nospor
No patrz, nie moge znalezc... domeny na ktorych to kiedys bylo teraz sa juz nieaktywne :/

Podam ci w skrocie idee, zlekka zmodyfikowana przeze mnie:
W tabeli drzewka IP nie masz id rodzica. Zamiast tego masz pelna sciezke od rodzica do dziecka.
Czyli jesli masz kategorie
kat1(id 1) ktora ma kategorie kat2(id 2) ktora ma kategorie kat3(id 3) to tak beda wygladaly rekordy:

ID, NAME, IP, LEVEL
1, kat1, 1., 0
2, kat2, 1.2., 1
3, kat3, 1.2.3., 2
Jak widzisz sciezka wyglada jak adres IP stad nazwa
Ja do sciezki dodaje tez ID aktualnego rekordu - mi to pomagalo w wyszukiwaniach
Dodaje rowniez LEVEL ktory mowi o stopnu zagniezdzenia elementu - rownie pomocne w pewnych przypadkach.
Ja rowniez na koniec kazdej sciezki dodaje kropke - tez mi to ulatwialo wyszukiwania

I teraz jak chcesz znalezc wszystkie kategorie nalezace do kat1 to dajesz:

select * from categories where IP like '1.%';
i juz.
Oczywiscie na pole IP musi byc zalozony index

Jak chcesz znalezc wszystkie nalezace do kat2 to dajesz
select * from categories where IP like '1.2.%';

To tak w skrocie smile.gif
arturpiotrowski
Dzięki dobry człowieku, ta wersja wygląda na znacznie prostszą do zrozumienia smile.gif Będę te metodę testował i się odezwę jak mi poszło smile.gif Muszę ogarnąć jeszcze kod php dodawania kategorii w takim drzewie ale spróbuję najpierw sam smile.gif

Dobrze myślę że do dodania kategorii potrzeba przynajmniej 2 zapytań? Jedno insert a drugie update z last insert id żeby wystawić na końcu ip id aktualnej kategorii? Poziom zagnieżdżenia mogę liczyć np po ilości kropek w ip kat. nadrzednej? A jeśli jest bez nadrzędnej dawać 0? Usuwanie kategorii poprzedzam sprawdzeniem ip z % na końcu, jak jest 1 rekord usuwam. Dobrze myślę?
nospor
Cytat
Dobrze myślę że do dodania kategorii potrzeba przynajmniej 2 zapytań? Jedno insert a drugie update z last insert id żeby wystawić na końcu ip id aktualnej kategorii?
Tak

Cytat
Poziom zagnieżdżenia mogę liczyć np po ilości kropek w ip kat. nadrzednej?
Poziom zagniezdzenia dla podkategorii znasz na podstawie kategorii nadrzednej czyli LEVEL KATEGORII NADRZEDNEJ +1

Cytat
Usuwanie kategorii poprzedzam sprawdzeniem ip z % na końcu, jak jest 1 rekord usuwam. Dobrze myślę?
A tego nie rozumiem. Co masz na mysli usuwanie kategorii? Mowisz o usuwaniu kategorii wraz z podkategoriami?
arturpiotrowski
Jesli wezme zwyklym delete bez sprawdzenia czy usuwania kategoria nie ma podkategorii to może się zdarzyć że usunę kategorię która ma jeszcze gałąź niżej i do czego będą się odwoływać te niższe podkategorie? To mam na myśli ale rozwinę to później bo pisanie z telefonu to dla mnie udręką 😀😀
nospor
Rozumiem.
Mozesz dodac jeszcze mimo wszystko pole ID_RODZIC i nalozyc na to relacje, ktora nie bedzie pozwalala na DELETE.
A sprawdzanie czy kategoria ma dzieci to tak, tak czy siak wypadaloby miec by wiedziec czy ich nie osieroci smile.gif
arturpiotrowski
Już rozumiem chyba wszystko o co pytałem wcześniej . Zastanawiam się tylko jak wyciągnąć wszystkie produkty z Wszystkich podkategorii i kategorii AGD. Jedyne co mi na myśl przychodzi to w tabeli kategorie_produkty dodać jeszcze pole IP i dac relacje z kategorie.IP i szukać w kategorie_produkty.IP przez like z % na koncu. Dobrze myślę? Oczywiście pole kategorie_produkty.IP przy zmianach w kategorie.IP by się apdejtowalo automatycznie.

Ps. Pisze z telefonu więc sorry za błędy 😀
nospor
Nie koniecznie. Pobierasz wpierw ID wszystkich szukanych kategorii a potem robisz drugie zapytanie by pobrac produkty z tych kategorii

select * from produkty_kategorie where id_kategorii in (id twojich kategorii po przecinku)
Oczywiscie dodajesz tam tez left join na produkty by miec pelne info o produktach.

Mozna tez pojsc dalej i to pierwsze zapytane wstawic do drugiego jako podzapytanie
select * from produkty_kategorie where id_kategorii in (tutaj zapytanie pobierajace ID szukanych kategorii)
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.