Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Zapytanie wybierz jeden rekord dla kategorii, SQL one record for category
Malinaa
post
Post #1





Grupa: Zarejestrowani
Postów: 573
Pomógł: 6
Dołączył: 21.07.2008

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


W bazie danych SQL, mam dwie tabele, jedna z artykułami "articles" druga z kategoriami artykułów "categories".

1. Jak napisać zapytanie, aby wybrać tylko po jednym artykule z każdej kategorii (artykuły np. najnowsze wpisy w kategorii)?
Tytuł artykułu i nazwa kategorii (wymagane dane) są w osobnych tabelach (tabele tworzą relacje).

2. Może ktoś wie jak to samo zrobić w Doctrine (Symfony), byłoby super.

Ten post edytował Malinaa 30.07.2021, 10:03:43
Go to the top of the page
+Quote Post
gornik
post
Post #2





Grupa: Zarejestrowani
Postów: 56
Pomógł: 9
Dołączył: 28.04.2010

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


Może coś takiego?
  1. SELECT * FROM articles
  2. WHERE id IN (
  3. SELECT MAX(id)
  4. FROM articles
  5. GROUP BY category_id
  6. );


I dla symfony 5:
  1. <?php
  2.  
  3. namespace App\Repository;
  4. use ...
  5. class ArticleRepository extends ServiceEntityRepository
  6. {
  7. // ...
  8. public function findNewestForCategory(){
  9. $em = $this->getEntityManager();
  10. $query = $em->createQuery("SELECT a FROM App\Entity\Article a WHERE a.id IN (SELECT MAX(a1.id) FROM App\Entity\Article a1 GROUP BY a1.category)");
  11. return $query->getResult();
  12. }
  13. }
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #3





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


Jeśli masz poprawnie zrobione relacje to ja bym to zrobił tak:

  1. foreach ($categories as $category) {
  2. $article = $category->getArticles()->first();
  3. }
Go to the top of the page
+Quote Post
nospor
post
Post #4





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Mega "optymalne" Lowiczak (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #5





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


... to dla dopełnienia aby nie było że skąd ta pętla ma wiedzieć że pierwszy rekord jest najnowszym artykułem, może np wyglądać to tak dla Twojej encji Category ale możesz oczywiście sortować jak chcesz i po dowolnym polu

  1. /**
  2.   * @ORM\OneToMany(targetEntity=Article::class, mappedBy="category")
  3.   * @ORM\OrderBy({"createdAt" = "DESC"})
  4.   */
  5. private $articles;


Ten post edytował LowiczakPL 8.09.2021, 14:22:36
Go to the top of the page
+Quote Post
nospor
post
Post #6





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Nadal nieoptymalne rozwiazanie (IMG:style_emoticons/default/wink.gif) W zasadzie jedno z najgorszych jakie mozna bylo podac
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #7





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


Przecież idzie to w 1 zapytaniu do bazy to dlaczego jest nieoptymalne, tak konkretnie o jaką rzecz chodzi?
Go to the top of the page
+Quote Post
nospor
post
Post #8





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




foreach ($categories as $category) {
$article = $category->getArticles()->first();
}

Od kiedy zapytanie w petli idzie jako jedno do bazy?
1) Tyle ile masz kategorii, tyle generujesz zapytan do bazy tu
2) getArticles() zwraca raczej wszystkie artykuly i dopiero jak je zwroci to ty pobierasz pierwszy z nich. Aczkolwiek tu sobie glowy nie dam uciac bo nie pamietam jak dziala doctrine w tym momencie choc na logike raczej tak jak mowie
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #9





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


... a no widzisz w Symfony jest inaczej niż zakładasz,

ta pętla i first() to tylko i wyłącznie 1 zapytanie do bazy danych

dla mnie to najprostsze, można to na repo zrobić ale po co, to zależy od potrzeby i od ilości danych

Ten post edytował LowiczakPL 8.09.2021, 14:45:03
Go to the top of the page
+Quote Post
nospor
post
Post #10





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




O ile jeszcze w first jestem w stanie uwierzyc, to co do petli mnie nie przekonasz (IMG:style_emoticons/default/wink.gif) Nie ma bata
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #11





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


w Symfony to też może być jako 1 zapytanie do bazy, gdzie masz zagnieżdżone relacje z encji Category do encji Article a ta ma relacje do encji Autor

  1. foreach ($categories as $category) {
  2. $autorName = $category->getArticles()->first()->getAuthor()->getName;
  3. }
Go to the top of the page
+Quote Post
nospor
post
Post #12





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Jak juz mowilem co do zagnieszdzen w doctrine klocic sie nie bede bo dawno nie pracowalem.
Ale petla to petla. Masz tam tyle zapytan ile kategori lecisz w petli i tego nie zmienisz
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #13





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


W przypadku Doctrine i Symfony zapomnij o standardowym myśleniu że odwołanie w pętli do encji to zapytanie do bazy, w Symfony tak nie ma, jeśli wiesz jak to się robi idzie to jako 1 zapytanie bez strat na pamięci i czasie wywołania skryptu i zapytania do bazy.

Jeśli znasz autorytet Symfony spytaj go a potwierdzi Ci bez wahania że to możliwe.

Ten post edytował LowiczakPL 8.09.2021, 15:02:21
Go to the top of the page
+Quote Post
nospor
post
Post #14





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




nawet w symfony petla to petla. tego nie zmienisz. bez dzialajacego przykladu nadal uwazam to za nieoptymalne
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #15





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


Moje rozwiązanie stosuje się wtedy kiedy właśnie potrzeba Ci optymalnego rozwiązania gdyż pada wydajność,

ono właśnie podnosi wydajność źle napisanego kodu zmniejszając ilość zapytań do bazy danych nawet z kilkuset do 1

co nie oznacza że to lekarstwo na wszelkie zło

tu jest jakaś namiastka o tym
https://www.doctrine-project.org/projects/d...erformance.html

Ten post edytował LowiczakPL 8.09.2021, 15:14:33
Go to the top of the page
+Quote Post
nospor
post
Post #16





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




W linku co podales nic nie widze na ten temat.


To inaczej, co wg ciebie bedzie zawieralo $article po wykonaniu tej petli?
foreach ($categories as $category) {
$article = $category->getArticles()->first();
}
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #17





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


$article to pierwszy element kolekcji czyli Obiekt encji Article zawierający najnowszy artykuł w konkretnej kategorii,

to może ten art https://www.uvdesk.com/en/blog/doctrine-pro...s-lazy-loading/
Go to the top of the page
+Quote Post
nospor
post
Post #18





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




"$article to pierwszy element kolekcji czyli Obiekt encji Article zawierający najnowszy artykuł w konkretnej kategorii,"
ja to wiem. autor chcial pierwszy element wszystkich kategorii. Po petli, autor dostanie tylko pierwszy artykul ostatniej kategorii

I tak wiem co to lazy loading. I sam mi wlasnie podales bron ze mowisz zle

"
These entities are then partially loaded and wrapped into a proxy object. At this point, only the id of the associated entity is known. Then when we further access a method or property of this proxied object, Doctrine will make a request to the database to load that property if it’s not already loaded.
"
czyli dla twojego drugiego przykladu nie bedzie jedno zapytanie na iteracje tylko kilka, w zaleznosci do ilu encji sie odwolasz. Wlansie o to mi chodzi. Ubzduralo ci sie ze symfony i doctrine robia magie ale to ni edo konca tak. (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
LowiczakPL
post
Post #19





Grupa: Zarejestrowani
Postów: 531
Pomógł: 55
Dołączył: 3.01.2016
Skąd: Łowicz

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


dokładnie tak jak piszesz, to autor zadecyduje co ma się stać,

ja tylko dałem przykład pobrania rekordu w pętli czyli zawsze najnowszego artykułu jak zna Symfony to raczej zauważy to że ta zmienna jest nadpisywana chyba nie jest .... robiony
Go to the top of the page
+Quote Post
nospor
post
Post #20





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




A ja ci tylko wyjasniam, ze to nie jest jedno zapytanie do bazy bo nie jest.
Odpal to sobie, odpal debug mode i sobie sprawdz (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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 - 18:04