Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z limitem w Doctrine2 w zapytanie które używa JOIN
Forum PHP.pl > Forum > PHP > Object-oriented programming
michael1986
Witam

Mam zapytanie takie:

  1.  
  2. $dql = "SELECT p, c FROM Entities\Product p LEFT JOIN p.ceny c";
  3.  
  4. $query = $em->createQuery($dql);
  5. $query->setMaxResults(2000);
  6.  


w jednym produkcie mam od 0 do 10 cen, jeśli dam limit to nie mam stałej liczby wyników na stronie nie mogę więc zrobić stronicowania, bo on daje bezpośrednio limit po zapytaniu SQL nie załapując tego że chodzi mi o 2000 pierwszych produktów a nie o 2000 pierwszych połączonych produkto-cen.


Pozdrawiam
krowal
Skoro chcesz same produkty to po co robisz LEFT JOIN do tabeli z cenami ? A jeśli już musi ten JOIN tam być to może GROUP BY wystarczy ?
michael1986
Cytat(krowal @ 10.01.2012, 18:53:57 ) *
Skoro chcesz same produkty to po co robisz LEFT JOIN do tabeli z cenami ? A jeśli już musi ten JOIN tam być to może GROUP BY wystarczy ?


bo chce żeby od razu załadował ich ceny, przy group by cen nie załaduje.

Próbowałem to obejść WHERE p.id IN ( SELECT produkt ... LIMIT 10 )

ale wychodzi na to że limit nie działa w podzapytaniach w mysql. Lekka kicha.
krowal
A jaką tam masz strukturę tabel? Po co trzymasz kilka cen dla produktu ? historia zmian czy coś innego ? Twój problem da się rozwiązać na co najmniej kilka sposobów, ale daj więcej info na temat tego co dokładnie chcesz osiągnąć.
michael1986
Cytat(krowal @ 10.01.2012, 20:11:37 ) *
A jaką tam masz strukturę tabel? Po co trzymasz kilka cen dla produktu ? historia zmian czy coś innego ? Twój problem da się rozwiązać na co najmniej kilka sposobów, ale daj więcej info na temat tego co dokładnie chcesz osiągnąć.


Kilka cen = kilka cen dla różnych klientów jest. Inne grupy cenowe dla grupy klienci zwykli i np. stali współpracownicy.

Jest taka możliwość z SQL:

  1.  
  2. SELECT * FROM A JOIN (SELECT * FROM A LIMIT 10) AS A1 ON A1.A.id
  3.  


pytanie czy da się to jakoś zrobić w tym SQL doctrinowym dwa zero?
adbacz
Chcesz zrobić zwykłe stronnicowanie rekordów? Jeśli tak to wystarczy:
  1. $dql = "SELECT p, c FROM Entities\Product p LEFT JOIN p.ceny c";
  2.  
  3. $result = $em->createQuery($dql)
  4. ->setFirstResult($start)
  5. ->setMaxResults($limit)
  6. ->getResult();


Gdzie:
$start = Od którego rekordu ma liczyć
$limit = Ile rekordów ma zwrócić
michael1986
Niestaczy bo te funkcje jeśli zadam im np. 10 na stronie to mi wypiszą 10 wpisów (cena * produkt), podczas gdy ja mogę mieć w jednym produkcie 3 ceny, w drugim 5 w trzecim 2. I będę miał całowity rozpierdziel w wyświetlanych danych.
Crozin
  1. SELECT p.id FROM product p INNER JOIN ... INNER JOIN ... WHERE p.category_id = :cid AND ... AND ... GROUP BY ... ORDER BY ... LIMIT ... OFFSET ...;
  1. SELECT p.id, p.name, pr.price, pr.GROUP ... FROM product p INNER JOIN ... INNER JOIN ... WHERE p.id IN (:lista_id_z_wcześniejszego_zapytania) GROUP BY ... ORDER BY ...
To jest ogólny mechanizm pobierania danych w takim przypadku, korzystając z Doctrine wygląda to z grubsza tak samo.

Przy czym istnieją narzędzia, które automatyzują ten proces (np. odpowiedni adapter dla Zend/Paginatora), gdzie jedyne co musisz zrobić to przekazać Doctrine'owskie zapytanie (obiekt Doctrine\ORM\Query), a one wygenerują pierwsze i odpowiednio zmodyfikują drugie po czym je wykonają.
michael1986
Cytat(Crozin @ 10.01.2012, 23:10:30 ) *
  1. SELECT p.id FROM product p INNER JOIN ... INNER JOIN ... WHERE p.category_id = :cid AND ... AND ... GROUP BY ... ORDER BY ... LIMIT ... OFFSET ...;
  1. SELECT p.id, p.name, pr.price, pr.GROUP ... FROM product p INNER JOIN ... INNER JOIN ... WHERE p.id IN (:lista_id_z_wcześniejszego_zapytania) GROUP BY ... ORDER BY ...
To jest ogólny mechanizm pobierania danych w takim przypadku, korzystając z Doctrine wygląda to z grubsza tak samo.

Przy czym istnieją narzędzia, które automatyzują ten proces (np. odpowiedni adapter dla Zend/Paginatora), gdzie jedyne co musisz zrobić to przekazać Doctrine'owskie zapytanie (obiekt Doctrine\ORM\Query), a one wygenerują pierwsze i odpowiednio zmodyfikują drugie po czym je wykonają.



tylko jak tą listę ID z poprzedniego zapytania przekazaćdo następego? czy zmienną mysql czy przez php? wydaje mi się że przez PHP to się "zmuli"
-=Peter=-
Zależy jak duży chcesz robić limit, jeśli na kilka tysięcy rekordów (tak jak w przykładzie) to faktycznie zapytanie i samo przesłanie zapytania z php do mysql może zamulić.
michael1986
Cytat(-=Peter=- @ 10.01.2012, 23:37:57 ) *
Zależy jak duży chcesz robić limit, jeśli na kilka tysięcy rekordów (tak jak w przykładzie) to faktycznie zapytanie i samo przesłanie zapytania z php do mysql może zamulić.


tak gdzieś 100, 500 albo nawet 5000 produktów. A tamto zapytanie pobierające ID to chyba nie mogę zrobić przez Doctrine? Bo nie bardzo mam pomysł jak wykorzystać doctrine do czegoś takiego, zwłasza że wolałbym w tablicy asocjacyjnjej wybrać samo ID a nie ładować zbędnych kolumn produktów - nie wiadomo kiedy pamięci zabraknie.

BTW. sam pomysł ładowania wszystkiego naraz zamiast 500 małych zapytań jest chyba ok? Z moich testów wychodzi że znacznie szybciej by to szło.

Cytat(Crozin @ 10.01.2012, 23:10:30 ) *
  1. SELECT p.id FROM product p INNER JOIN ... INNER JOIN ... WHERE p.category_id = :cid AND ... AND ... GROUP BY ... ORDER BY ... LIMIT ... OFFSET ...;
  1. SELECT p.id, p.name, pr.price, pr.GROUP ... FROM product p INNER JOIN ... INNER JOIN ... WHERE p.id IN (:lista_id_z_wcześniejszego_zapytania) GROUP BY ... ORDER BY ...
To jest ogólny mechanizm pobierania danych w takim przypadku, korzystając z Doctrine wygląda to z grubsza tak samo.

Przy czym istnieją narzędzia, które automatyzują ten proces (np. odpowiedni adapter dla Zend/Paginatora), gdzie jedyne co musisz zrobić to przekazać Doctrine'owskie zapytanie (obiekt Doctrine\ORM\Query), a one wygenerują pierwsze i odpowiednio zmodyfikują drugie po czym je wykonają.


a możesz jeszcze podać linka do takiego narzędzia?
Crozin
@Google: doctrine extensions, Google: doctrine zend paginator adapter
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.