Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][SQL]Optymalne wyciąganie rekordów z danej kategorii
Forum PHP.pl > Forum > PHP
matix
Siema,
pytanie do mądrzejszych ode mnie i bardziej doświadczonych. W jaki sposób wyciągacie n rekordów z x kategorii. Przykład?

Cytat
Pobierz 5 kategorii oraz po 5 filmów do każdej z nich.

Zakładając, że schemat bazy jest bardzo prosty

Kod
category:
cat_id
cat_name

video:
video_title
video_cat_id (references cat_id)


Obecnie po głębszych przemyśleniach moje rozwiązania:

1. wyciągamy np. 5 kategorii zapytaniem:
  1. SELECT cat_name FROM cms_categories LIMIT 0, 5


Następnie tworzymy drugie zapytanie, które wyciąga po 4 filmy do danej kategorii, wyglądające mniej więcej tak:
  1. (SELECT video_id,video_title,video_length,video_image,video_views,video_rating,video_cat_id,video_service_id FROM cms_views_video WHERE video_cat_id = 10 AND video_state = 1 LIMIT 0, 4)
  2. UNION
  3. (SELECT video_id,video_title,video_length,video_image,video_views,video_rating,video_cat_id,video_service_id FROM cms_views_video WHERE video_cat_id = 9 AND video_state = 1 LIMIT 0, 4)
  4. UNION
  5. (SELECT video_id,video_title,video_length,video_image,video_views,video_rating,video_cat_id,video_service_id FROM cms_views_video WHERE video_cat_id = 8 AND video_state = 1 LIMIT 0, 4)


2. Jedno duże zapytanie JOIN. To akurat mój nowy pomysł, jednak nie wiem jakby takie zapytanie miało wyglądać. Generalnie wyglądałoby to mniej więcej tak, że te 2 zapytania byłyby ze sobą połączone, prawdopodobnie to drugie byłoby warunkiem WHERE cat_id IN (), jednak to jest znacznie bardziej skomplikowane.

Więc teraz pytanie do Was, w jaki sposób rozwiązujecie takie rzeczy?
potreb
Ja bym zrobił inaczej, pobieram kategorie, robie LEFT JOIN video i pobieram rekordy wideo gdzie video_cat_id ON cat_id, jedno krotkie zapytanie.
matix
No ok, a w jaki sposób wyciągniesz określoną ilość filmów dla danej kategorii?
sniver
  1. SELECT cat_name FROM cms_categories LIMIT 0, 5


to bym zrobił nieco inaczej, tylko dlatego by optymalnie działało. Bo po co np. pokazywać puste kategorie jak i tak tam nic nie ma smile.gif

  1. SELECT
  2. `c`.`cat_name` AS `name`,
  3. (
  4. SELECT COUNT(1) FROM `cms_views_video` AS `v`
  5. WHERE
  6. (`v`.`video_cat_id` = `c`.`video_cat_id`)
  7. ) AS `licz`
  8.  
  9. FROM
  10. `cms_categories` AS `c`
  11.  
  12. HAVING
  13. (`LICZ` > 0)


Dalszą część zostawił bym jak jest...

Jest jeden szkopuł, jeśli stworzył byś mechanizm z zagnieżdżaniem kategorii w stylu Rodzic - dzieci - dziecko dziecka - dziecko ... - dziecko n (nie wiem czy dobrze do opisałem) musiał byś oprzeć to na jakimś liczniku..

tyle ode mnie w tej sprawie smile.gif
matix
@Sniver, podałeś dokładnie to samo co ja, tylko jeszcze mniej optymalne (samo "having" jest dość ciężkie).

Bardziej zależy mi na optymalnym rozwiązaniu mojego problemu poprzez jedno zapytanie.
WoGuziczek
Gdybym ja zaczął robić coś takiego utworzyłbym nową kolumnę count w tabeli category.
Po wykonaniu tego trzeba w miejscu gdzie dodajesz/usuwasz filmy dodać odpowiedni skrypt, który doda lub odejmie od licznika w zależności od tego co zrobisz.
Po zrobieniu tego jednorazowo trzeba odpalić mały skrypcik, który wykona
  1. SELECT COUNT(*) WHERE video_cat_id = 'tutaj id kazdej kategorii pobranej zapytaniem przez SELECT cat_id FROM category'
dla każdej kategorii i zapisze w kolumnie count ilość filmów się w niej znajdujących.

Teraz już masełko, bo robisz tak jak polecił potreb.
Jedno małe zapytanie z jednym LEFT JOIN
aio
Kod
SELECT  *
FROM    (
        SELECT  c.*
        FROM    category c, (SELECT @L:=0, @C:=0) init
        -- WHERE cat.id IN (1,2,3)  -- ewentualnie ręczny wybór kategorii
        LIMIT /* liczba kategorii: */ 5
        ) c
LEFT JOIN video v
ON      IF(video_cat_id = cat_id
        AND IF(@L=cat_id,@C:=@C+1,(@L:=cat_id) AND @C:=0) <= /* liczba video: */ 5
        ,1,0)
matix
@aio: To co napisałeś wydaje się być działającym rozwiązaniem, ale czy na pewno szybszym od tego co ja zaproponowałem? Jak z wydajnością takich zapytań?
aio
Cytat(matix @ 25.04.2010, 23:13:51 ) *
@aio: To co napisałeś wydaje się być działającym rozwiązaniem, ale czy na pewno szybszym od tego co ja zaproponowałem? Jak z wydajnością takich zapytań?

ich weiss nicht - ale mógłbyś sprawdzić, i pewnie nikt by nie miał za złe gdybyś ogłosił wyniki winksmiley.jpg
dałem warunek do ON żeby filtrowało na jak najniższym poziomie.
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.