Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Problematyczne zapytanie do bazy danych
Forum PHP.pl > Forum > Przedszkole
Sketchy
Hej wszystkim,

ponieważ nie mogę za bardzo znaleźć jakiegoś rozwiązania w internecie postanowiłem, że może ktoś tutaj byłby w stanie pomóc mi z problemem.

Konstrukcja tabel

#profil
id | nazwa | opis | status

#profil_kategoria
id | sub_category | profil

#sub_category
id | main_category | nazwa

#main_category
id | nazwa


Co potrzebuję osiągnąć?
1. Wyciągnąć z bazy danych wyniki wyszukiwania w postaci:

REKORD =
nazwa,
id kategorii głównych (main_category), do których przypisany jest profil oraz...
id wszystkich podkategorii, do których przypisany jest profil za pomocą tabeli #profil_kategoria.

Następnie podczas wyszukiwania w przypadku np. lista.php?subkategoria=4, aby zapytanie sprawdziło, które profile należą do tej podkategorii... ale mimo wszystko aby na liście pobrały się wszystkie podkategorie...

Dodam, że profile mogą być przypisane do kilku podkategorii.


Jak obecnie wygląda moje zapytanie?

  1. SELECT a.nazwa, group_concat(d.nazwa) AS kategoria, group_concat(b.sub_category) AS kategoriaid, group_concat(c.nazwa) AS podkategoria FROM profil a LEFT JOIN profil_kategorie b ON b.profil = a.id LEFT JOIN sub_category c ON b.sub_category = c.id LEFT JOIN main_category d ON d.id = c.main_category WHERE 1 GROUP BY a.id HAVING podkategoria LIKE '%nazwa_kategorii pobieranej z get%'


Problem w tym, że pomimo pobierania kolumny "kategoriaid" i tak nie mogę jej wykorzystać.

Zapytanie... niestety trochę długo trwa i tutaj tkwi problem. Tak naprawdę nie potrzebuje wyciągać całych nazw kategorii i mógłbym wykorzystać same numerki kategorii. Zastanawiałem się, aby zrobić HAVING kategoriaid LIKE '%nr podkategorii%' wyszukiwanej w ciągu zrobionym przez group_concat() tj. np. "45,66,23"... ale nic z tego, bo HAVING LIKE nie ma chyba(?) zastosowania do numerów.

Znacie może jakieś rozwiązanie? Które pozwoliło by mi zoptymalizować to zapytanie, aby je trochę przyspieszyć? i zamiast wyciągać całych nazw kategorii po prostu zadziałać na numerach? - niestety potem zapytanie będę musiał dodatkowo rozbudować o województwa... a tak jak kat. - profile mogą być przypisane do więcej niż jednego.

Mam nadzieję, że udało mi się opisać dokładnie mój problem.
Dzięki, pozdrawiam.
pmir13
Zapytanie trwa długo, bo robisz wielki left join z kilku tabel, grupujesz wszystko i dopiero filtrujesz gotowe grupy przy pomocy HAVING, czyli robisz wszystko od końca.
Left join stosujemy wtedy, gdy chcemy wszystkie rekordy z lewej tabeli wraz z odpowiadającymi wg warunku ON rekordami z prawej tabeli, a gdy takich w prawej tabeli nie ma to wciąż chcemy rekordy z lewej, tyle że w prawej zamiast wartości będa NULL. Natomiast INNER JOIN ( można pisać sam JOIN ) wybiera tylko te rekordy, które potrzebujemy - jeśli w obu tabelach nie ma takich wspólnie spełniajacych warunek złączenia to prostu są ignorowane.

W tym wypadku powinieneś zacząć od warunku w nazwą podkategorii w zwykłym WHERE i powoli rozbudowywać swój rowset dodając potrzebne JOIN, nie widzę potrzeby by to były LEFT JOIN.

Jeśli potrzebujesz zapytania, to wyjaśnij dokładniej o co chodzi, najlepiej na konkretnym przykładzie zawierającym kilka profili, kategorii i podkategorii i podaj oczekiwany wynik.
Sketchy
Witam ponownie,

@pmir13 - dzięki za pomoc... kombinowałem i jakoś nie do końca mi jednak idzie, dlatego postanowiłem, że jeszcze raz napiszę.

dłubałem dłubałem wydłubałem coś... ale jednak tracę pomysły... może totalnie amatorsko od końca wszystko robię, ale może ktoś będzie w stanie mi pomóc przy konstrukcji zapytania na bazie mojego szkicu...



Zapytania wyglądały już naprawdę na milion sposobów z JOIN'em, LEFT JOIN'em... ale ostatni twór jest chyba przesadzony, bo już nie mam pomysłu na warunkowanie pobranych danych...

  1. SELECT SQL_NO_CACHE *,
  2. (
  3. SELECT GROUP_CONCAT(sub_category.nazwa SEPARATOR ', ') AS kat
  4. FROM `profil_kategorie` JOIN sub_category ON profil_kategorie.sub_category = sub_category.id
  5. GROUP BY profil_kategorie.profil
  6. HAVING profil_kategorie.profil = profil.id
  7. ) AS kategorie,
  8. (
  9. SELECT GROUP_CONCAT(wojewodztwa.id SEPARATOR ',') AS woj
  10. FROM `profil_region` JOIN wojewodztwa ON profil_region.region = wojewodztwa.id
  11. GROUP BY profil_region.profil
  12. HAVING profil_region.profil = profil.id
  13. ) AS region,
  14. (
  15. SELECT GROUP_CONCAT(wojewodztwa.id SEPARATOR ',') AS woj
  16. FROM `profil_kontakt` JOIN wojewodztwa ON profil_kontakt.wojewodztwo = wojewodztwa.id
  17. GROUP BY profil_kontakt.id_profil
  18. HAVING profil_kontakt.id_profil = profil.id
  19. ) AS wojewodztwa
  20. FROM `profil`
  21. WHERE 1
  22. GROUP BY profil.id;
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.