Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: problem z zapytaniem
Forum PHP.pl > Forum > Bazy danych > MySQL
fido20
Witam,

Mam tabele

| IdPorduktu | IdKategorii | NazwaProduktu | DataDodania |

Chce z niej wyciągnąć po 5 produktów dla każdego id_kategorii posortowane według DataDodanie Desc (5 najnowszych prodktów dla każdej z kategorii)
Czy jest to mozliwe w jednym zapytaniu ?
kicaj
Tytuluj tematy bardziej opisowo...

Odp. Tak
prond
Możliwe, ale w MySQL wcale nie takie proste. To, co chcesz osiągnąć wymaga funkcji rankingujących, których nie ma w MySQL.
Można to obejść wykorzystując zmienne:
  1. SET @intRank := 0;
  2. SET @intLastCategoryId := 0;
  3. SELECT
  4. *
  5. FROM ( SELECT
  6. products.*,
  7. CASE
  8. WHEN @intLastCategoryId <> products.category_id
  9. THEN @intRank := 1
  10. ELSE @intRank := @intRank + 1
  11. END AS rank,
  12. @intLastCategoryId := products.category_id
  13. FROM products ORDER BY
  14. products.category_id
  15. ) AS t
  16. WHERE t.rank < 6;
phpion
Cytat(kicaj @ 20.12.2007, 20:23:36 ) *
Odp. Tak

Tak? W takim razie proszę napisz mi takowe zapytanie - będę naprawdę wdzięczny.
Mój MySQL (5.0.26) krzyczy:
Kod
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery

Więc może jeśli nie znasz rozwiązania to nie wprowadzaj ludzi w błąd.
nevt
Cytat
Tak? W takim razie proszę napisz mi takowe zapytanie - będę naprawdę wdzięczny.
Mój MySQL (5.0.26) krzyczy:
KodThis version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery
Więc może jeśli nie znasz rozwiązania to nie wprowadzaj ludzi w błąd.

och... ludzie małej wiary, proszę oto kod działającvy w MySQL...
dla uproszczenia zapisu przyjmijmy:
idProduktu = pid
idKategorii = cid
dataDodania = dd
a tabelka to po prostu `tabela`:
  1. SELECT * FROM tabela AS a
  2. WHERE (SELECT COUNT(cid) FROM tabela AS b WHERE (b.dd > a.dd) AND (b.cid = a.cid)) < 5;

oczywiście zamiast 5 można wstawić dowolną inną liczbę.
i kto tu kogo wprowadza w błąd??
phpion
@nevt: Jeśli Twoje rozwiązanie faktycznie działa (a nie mam jak sprawdzić) to cofam moją wypowiedź i idę schować się do szafy.
wstydnis.gif brzydal.gif worriedsmiley.gif
prond
@nevt : Ciekawe podejscie do tego problemu. Nie wpadlem nigdy na to, bo probowalem to zrobic tak jak w ORACLE (rank() over partition). Przetestowalem sobie Twoje zapytanie - dziala pieknie, ale jest jeden problem - dla ok. 6mln rekordow robi sie bardzo bardzo wolne. Pewnie dlatego, ze podzapytanie w WHERE budowane jest dla kazdego rekordu, a dla tego podzapytania MySQL nie wykorzystuje INDEX'ow.

Rozwiazanie ze zmiennymi tez nie jest najlepsze, ale sa tylko 2 loopy przez cala tabelke i lata duzo szybciej.
nevt
to oczywiste że moja konstrukcja jest nieoptymalna - sam ją stosuję tylko na b. krótkich tabelkach...
chodziło tylko o demonstrację, że jest to technicznie możliwe w jednym zapytaniu, bez zmiennych pomocniczych i pętli...

pozdrawiam wszystkich.
fido20
Dzięki wszystkim za zainteresowanie i pomoc smile.gif
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.