Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Liczenie rekordów wielu polach
Forum PHP.pl > Forum > Bazy danych > MySQL
acztery
witam,

Mam taki mały kłopot mam nadzieję, że nie skąplikuje tego zabardzo.


chce policzyc produkty danej kategori i wszystkich ich dzieci dzialac dziala ale mam ponad 2000 tys zapytan bez pytań .....


w tabeli kategorie

mam id|name|parent

i chce zeby powiedzmy jak podam jakas glowna kategorie to skrypt sprawdzi jakie ma dzieci i zrobi mi zapytanie typu

  1. $sql = "SELECT id,parent
  2. FROM categ
  3. WHERE id=3232 AND id=1245 itd ...."; w zaleznosci od ilosc dzieci ma ktos jakis pomysl


potrzebne mi to do sklepu np ktos wejdzie do kategori komputery i pokazuje mu wszystkie produkty z tej kategori i wszystkich dzieci nalezoczych do niej
Kuziu
Ale ja czegoś chyba nie rozumię.

Skoro chcesz wyszukać dzieci kategorii np. 5 to robisz zapytanie
  1. SELECT id, name
  2. FROM categ
  3. WHERE parent='5'

I dostajesz dzieci kategorii 5
acztery
hehehe nie o to chodzi wiem do czego jest WHERE ale jezeli w kategori 5 jest 100 innych to co to ich nie policze ... musze najpier dowiedziec sie ID wszystkich dzieci kategori w ktorej jestem
Kuziu
Przedstaw dokładniej problem bo z tego co piszesz nic nie można zrozumieć.

Jakiś przykład może.
nospor
  1. SELECT *
  2. FROM prod
  3. p, categ c
  4. WHERE p.id_cat=c.id AND (c.id = 5 OR c.parent=5)
Cos takiego?

ps: przenosze na bazki
acztery
ludzie wy czytac nie umiecie questionmark.gifquestionmark.gifquestionmark.gifquestionmark.gifquestionmark.gifquestionmark.gif jak mam to policzyc jak nie znam wszystkich ID dzieci to jak mam zrobic takiego selecta.



  1. $sql = "SELECT id,parent
  2. FROM categ
  3. WHERE id=32342422 AND id=1242245 AND id=1244245 AND id=1245 AND id=12442425 AND id=122245 AND id=124e5 AND id=142245 AND id=1245 AND id=12424245 AND id=1245 AND id=12345 AND id=124425 AND id=1424245 itd ....";


i trzeba to wygenerowac np do zmiennej $where

  1. id=32342422 AND id=1242245 AND id=1244245 AND id=1245 AND id=12442425 AND id=122245 AND id=124e5 AND id=142245 AND id=1245 AND id=12424245 AND id=1245 AND id=12345 AND id=124425 AND id=1424245
nospor
yyyy? po co te nerwy?
Moje zapytanie sprawdza czy id rodzica zgadza się z tym id co chcesz. To chyba ty nie umiesz czytac winksmiley.jpg Skoro znam id rodzica, to na grzyba mi id dziecka?
FiDO
Ja tutaj widze blad na etapie projektowania bazy.. z taka struktura jak podajesz nie da sie tego sensownie zrobic i musisz najpierw pobrac wszystkie wezly dzieci (rekurencyjnie az do samego konca) i dopiero potem wyswietlac.
Gdybys zastosowal jakas inteligentniejsza forme drzewek SQL to daloby sie to zrobic latwiej.. teraz to juz troche musztarda po obiedzie.
nospor
hmmm, znaczy, że dana kategoria może mieć dzieci, wnuki i prawnuki? Myslalem ze ograniczamy się tylko do dzieci (pierwszego poziomu). Dlatego takie zapytanie dalem. Jesli jest kilka poziomow dzieci, to faktycznie musztarda po obiedzie winksmiley.jpg
Trzeba by najpierw nasmazyc pare rekurencyjnych zapytan by pobrac id, a dopiero potem produkty
acztery
FIDO . a jak to rozwiązać jak zaprojektowawć zeby to nie brały tyle zapytać. questionmark.gif jaka struktura bo nie wiem na takiej struktrzue nie da sie tego zrobic ?

PS struktura categ jest taka:

  1. CREATE TABLE `sys_cats` (
  2. `CatID` varchar(32) NOT NULL DEFAULT '',
  3. `CatLang` char(2) NOT NULL DEFAULT '',
  4. `CatName` varchar(255) NOT NULL DEFAULT '',
  5. `CatDescription` text NOT NULL,
  6. `CatPermAccess` text NOT NULL,
  7. `CatPermEdit` text NOT NULL,
  8. `CatPermCreate` text NOT NULL,
  9. `CatPermPublish` text NOT NULL,
  10. `CatIconID` varchar(32) NOT NULL DEFAULT '',
  11. `CatIconFile` varchar(255) NOT NULL DEFAULT '',
  12. `CatParentID` varchar(32) NOT NULL DEFAULT '',
  13. `CatAuthorID` varchar(32) NOT NULL DEFAULT '',
  14. `CatHidden` enum('N','Y') NOT NULL DEFAULT 'N',
  15. `CatSystem` enum('N','Y') NOT NULL DEFAULT 'N',
  16. `CatDeleted` enum('N','Y') NOT NULL DEFAULT 'N',
  17. `CatPriority` mediumint(9) NOT NULL DEFAULT '0',
  18. `CatCreateDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  19. `CatAdult` enum('N','Y') NOT NULL DEFAULT 'N',
  20. `DefaultDoc` varchar(32) NOT NULL DEFAULT '',
  21. `DocLinkFormat` varchar(255) NOT NULL DEFAULT 'page.php?DOC={$DocID}',
  22. `CatLinkFormat` varchar(255) NOT NULL DEFAULT 'page.php?CAT={$CatID}',
  23. `imgrek` enum('Y','N') NOT NULL DEFAULT 'N',
  24. PRIMARY KEY (`CatID`,`CatLang`)
  25. ) TYPE=MyISAM;


ALBO jakto zrobic jednymzapytaniem

Cytat
Ja tutaj widze blad na etapie projektowania bazy.. z taka struktura jak podajesz nie da sie tego sensownie zrobic i musisz najpierw pobrac wszystkie wezly dzieci (rekurencyjnie az do samego konca) i dopiero potem wyswietlac.
FiDO
http://forum.php.pl/index.php?showtopic=35091 - tutaj masz troche informacji na temat drzewek w SQL'u

Akurat do tego typu zapytania nadaly by sie np. drzewka Materialized Path (jedno zapytanie do pobrania produktow z wybranej galezi), ale musisz przemyslec jakie beda najczestsze operacje i w ogole co bedzie potrzebne, zeby dobrac jakas optymalna strukture. Lektura powyzszego watku powinna to troche ulatwic.
acztery
spoko LIKE to dobre rozwazanie ale za duzo zmian to juz teraz ... np allegro.pl widze ze ma w adresie jeden ciagly numerkategorii i na podstawie jedo tworza where smile.gif gdzie tkwi fenomen
FiDO
Jest przeciez wiele roznych sposobow na realizacje drzewek w bazie.. skad pewnosc, ze allegro chodzi w ogole na MySQL ? Byc moze maja jakas bardziej zaawansowana baze z procedurami.. wtedy mozna juz zaszalec.
Zreszta nawet przy takich sciezkach mozna to zrobic, tylko ze dwoma zapytaniami (albo zapytaniem z podzapytaniem), pierwsze pobiera sciezke dla danej kategorii, a drugie produkty z tej kategorii (i podrzednych).
acztery
to jak to wlasnie zrobic dwuma zapytaniami po teraz robi ponad 2 tys przy duzej ilosc kategori a jak bedzie duzoludzi na stronie to strona bedzie sie otwierala miesac??
FiDO
Mniej wiecej tak:
Kod
SELECT p.*
FROM produkty p
INNER JOIN kategorie k ON k.id = p.kat_id
WHERE k.path LIKE CONCAT( (SELECT path
                            FROM kategorie
                            WHERE id = 1234) , '%')
DeyV
W mysql nie można tego zrobić przy pomocy 2 zapytań, jeśli nie chce się wykorzystać drzewka a'la IP, ponieważ wersja instalowana w tej chwili na większości serwerów nie pozwala narazie na tworzenie procedur.

Wydaje mi się jednak, że w twoim przypadku dodanie odpowiedniego pola z informacują o pozycji danej katerogii w drzewie i zapisanie tego w postaci adresu "IP" czyli numer_kategroii. numer _odkategorii ...
i późniejsze wyszukiwanie całej gałęzi przy pomocy LIKE.
Zauważ, że wygenerowanie takich informacji dla istniejących danych musiałbyś zrobić tylko raz.
A dla kolejnych, dodawanych dopiero - uzupełniałbyś to pole na bieżąco.
acztery
jezeli nic innego mi nie przyjdzie do glowy to tak zrobie a roziwazanie tego typu zeby dodac pole level ? ale wtedy bede musial znowu wyszukac wszystkie levele danej kategorii nie bylo by tego tyle co teraz


PS z tym ze ja dodalem 2 tys kategori na tym co teraz mam to uunac zmienic na IP i znowu dodawac Masakra ..
FiDO
Cytat(acztery @ 2006-02-27 12:38:31)
PS z tym ze ja dodalem 2 tys kategori na tym co teraz mam to uunac zmienic na IP i znowu dodawac Masakra ..

Przeciez nikt Ci nie kaze robic tego recznie... Prosty skrypcik iterujacy po drzewku od korzenia zalatwi sprawe.
acztery
OK robie to tak ze dodam jedno pole o nazwie path i tam bedzie wszystko i na podstawie jego bede liczyl .

ale przy dodawaniu kategorii nie wiem zabardzo jak te path ma sie ukladac


jak dodaje do 1kategori to mam 1 jak do 2 to 2

jak wejde do 2 i tam cos dodam to 2.1 ma ktos cos co generuje cos takiego ?
DeyV
path wygląda tak:

1.3.15.142

Dodanie kolejnego liścia do takiej gałęzi:

  1. SELECT path
  2. FROM ...
  3. ..
  4.  
  5.  
  6. INSERT
  7. INTO ...
  8. SET
  9. path = " $sPath . '.' . $iParentId "
  10. ...
acztery
wiem ale jak tworzyc te zmienne zeby bylologiczne i niebylo balaganu
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.