Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Problem z limitem w Doctrine2 w zapytanie które używa JOIN
michael1986
post
Post #1





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 19.09.2005

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 11)
krowal
post
Post #2





Grupa: Zarejestrowani
Postów: 561
Pomógł: 72
Dołączył: 15.11.2006

Ostrzeżenie: (0%)
-----


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 ?
Go to the top of the page
+Quote Post
michael1986
post
Post #3





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 19.09.2005

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
krowal
post
Post #4





Grupa: Zarejestrowani
Postów: 561
Pomógł: 72
Dołączył: 15.11.2006

Ostrzeżenie: (0%)
-----


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ąć.
Go to the top of the page
+Quote Post
michael1986
post
Post #5





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 19.09.2005

Ostrzeżenie: (0%)
-----


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?
Go to the top of the page
+Quote Post
adbacz
post
Post #6





Grupa: Zarejestrowani
Postów: 532
Pomógł: 24
Dołączył: 15.04.2011
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


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ć
Go to the top of the page
+Quote Post
michael1986
post
Post #7





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 19.09.2005

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
Crozin
post
Post #8





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


  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ą.
Go to the top of the page
+Quote Post
michael1986
post
Post #9





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 19.09.2005

Ostrzeżenie: (0%)
-----


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"
Go to the top of the page
+Quote Post
-=Peter=-
post
Post #10





Grupa: Zarejestrowani
Postów: 304
Pomógł: 51
Dołączył: 4.02.2005
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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ć.
Go to the top of the page
+Quote Post
michael1986
post
Post #11





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 19.09.2005

Ostrzeżenie: (0%)
-----


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?

Ten post edytował michael1986 10.01.2012, 23:46:43
Go to the top of the page
+Quote Post
Crozin
post
Post #12





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@Google: doctrine extensions, Google: doctrine zend paginator adapter
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 17:50