Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MYSQL] Pobieranie tylko powiązanych rekordów
Forum PHP.pl > Forum > Przedszkole
The Night Shadow
Mamy trzy tabele.

produkty - tabela z produktami
kategorie - tabela z kategoriami gdzie kolumna id_matki świadczy o istnieniu podkategorii kategorii z wpisanym tam ID
produkty_kategorie - relacja na zasadzie id_produktu <-> id_kategorii (powód: wiele kategorii do jednego produktu i odwrotnie)

Sytuacja jest następująca:

Mamy 5000 produktów, 1000 kategorii schierarchozowanych w postaci drzewka kategorii. Powiedzmy, że drzewko kategorii wygląda tak:

Komputery
---- PC
---- LAPTOPY
---- MAC

Kiedy kliknę w kategorie komputery powinny pokazać sie wszystkie produkt przypisane do niej oraz do jej kategorii. System zakłada, że nie ma ilości ograniczenia zagłębień w podkategoriach.

Tak więc musimy pobrać te produkty, dla których w tabeli produkty_kategorie istnieje powiązanie na zasadzie id_produktu -> id_kategorii. Dzieje się to dla wszystkich 4 kategorii.

Powstaje coś takiego:

  1. EXISTS (SELECT id_produktu, id_kategorii
  2. FROM produktykategorie WHERE id_produktu = produkty.id AND id_kategorii = '1'
  3. LIMIT 1 ) OR EXISTS (SELECT id_produktu, id_kategorii
  4. FROM produktykategorie WHERE id_produktu = produkty.id AND id_kategorii = '2'
  5. LIMIT 1 ) OR EXISTS (SELECT id_produktu, id_kategorii
  6. FROM produktykategorie WHERE id_produktu = produkty.id AND id_kategorii = '3'
  7. LIMIT 1 ) OR EXISTS (SELECT id_produktu, id_kategorii
  8. FROM produktykategorie WHERE id_produktu = produkty.id AND id_kategorii = '4'
  9. LIMIT 1 )


Mamy więc 4 id kategorii. Zapytanie tego typu jest masakrycznie mało wydajne. Przy kilku tysiącach produktów, kiluset kategoriach i kategorii, która ma powiedzmy kilkanaście podkategorii tworzy się zapytnie wypierniczające serwer.

Moje pytanie brzmi jak wykonać taki proces w sposób możliwie najbardziej ergonomiczny?
ddiceman
Proponuje:
  1. <?php
  2. $categoryId =...; //id kategorii od ktorej zaczynasz
  3.  
  4. $finaltable = array($categoryId);
  5. for($i=0; $i<count($finaltable);){
  6.    $result = mysql_query('SELECT id FROM kategorie WHERE id_matki IN ('.implode(',', array_slice($finaltable, $i)).');';
  7.    while($row = mysq_fetch_row($result)){
  8.         $finaltable[] = $row['id'];
  9.    }
  10.    $i+=mysql_num_rows($result)+1;
  11. }
  12. $result = mysql_query('SELECT produkty.* FROM produkty LEFT JOIN produkty_kategorie ON produkty.id = produkty_kategorie.id_produktu WHERE produkty_kategorie.id_kategorii IN ('.implode(',', $finaltable).');');
  13. ?>

Koncowe zapytanie powinno zwrocic produkty (pisane z palca, musisz sprawdzic)
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.