Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: SELECT kilku unikalnych rekordów zgrupowanych wg jednej kolumny
Forum PHP.pl > Forum > Bazy danych > PostgreSQL
lukass
Witam,

mam pewien problem: istnieje sobie tabela z news'ami, zawiera m.in. kolumnę z ID kategorii (FK), chciałbym za jednym selectem wybrać np.: 5 ostatnich unikalnych tytułów newsów dla każdego ID kategorii w tej tabeli. Czy jest to mozliwe?

Pozdrawiam
LukasS
Sedziwoj
Możliwe jest, tylko że nie do końca to ma sens. Bo potem jak rozdzielisz które rekordy do której kategorii należą, przeglądając je? To już lepiej jest zadać parę zapytań. Tylko aby nie zapomnieć o indeksie btree na dacie.
lukass
bralbym takie rzeczy jak id newsa, tytul, id kategorii i wg id kategorii bym sobie to rozdzielal. Jako ze dzialaloby to na stronie glownej, robienie wielu zapytan moze dobijac baze :/

Masz moze gdzies jakis abstrakcyjny przyklad jak to zrobic?
Zbłąkany
Sedziwoj, a czemu bez sensu? Ja bym zrobił tak:
kategorie
+id
+nazwa
newsy
+id
+id_kategorii
+tytul
+data_dodania
...itd
  1. SELECT
  2. k.id,
  3. k.nazwa,
  4. n.*
  5. FROM kategorie k
  6. LEFT OUTER JOIN ( SELECT id,
  7. id_kategorii,
  8. tytul,
  9. data_dodania
  10. FROM newsy ORDER BY data_dodania DESC LIMIT 5
  11. ) AS n
  12. GROUP BY k.id;
Sedziwoj
@Zbłąkany
Wiem że tak można, ale mi się to nie podoba.
Tak swoją drogą, słówko OUTER jest zbędne, bo tylko takie może być i można je pominąć.
lukass
  1. SELECT C.id_c,C.cat_name,N.* FROM categories AS C
  2. LEFT JOIN ( SELECT id_n,title,created FROM news WHERE STATUS = 1 ORDER BY publish DESC LIMIT 5 ) AS N
  3. GROUP BY C.id_c


Tak wygląda faktyczne zapytanie, a sypie się na GROUP:

Kod
ERROR:  syntax error at or near "GROUP" at character 157


Ogólnie przy GROUP (w postgre) powinno zawrzeć się wszystkie brane kolumny, prawda? Dodałem też złączenie po id_c, wymieniłem wszystkie kolumny, które pobierane są z obu tabel i dziwne kwiatki powychodziły.

W każdym razie już wiem, że od złej strony podchodziłem do tego problemu, jakoś dziwnie mi się ubzdurało branie najpierw newsów a później kategorii.
Zbłąkany
Możnaby to jeszcze bez GROUP BY zrobić biggrin.gif
  1. SELECT * FROM kategorie k LEFT OUTER JOIN (SELECT * FROM newsy ORDER BY data_dodania DESC LIMIT 5 ) AS n ORDER BY k.nazwa ASC, n.data_dodania DESC;
Sedziwoj
@Zbłąkany
Czy Ty sprawdzasz te SQL'e?
Cytat
For the INNER and OUTER join types, a join condition must be specified, namely exactly one of NATURAL, ON join_condition, or USING (join_column [, ...])


Do tego nie zrobi ono, poprawione, tego co byś chciał, bo wybierze 5 rekordów z "newsy" i je dołączy do "kategorie".
A przecież ma wybrać po 5 rekordów dla każdej kategorii.

I coś mi się wydaje, że nie da się tego ładnie zrobić.
  1. SELECT * FROM
  2. (SELECT *,(SELECT n.add_date FROM news AS n WHERE n.category_id = c.id ORDER BY n.add_date OFFSET 5 LIMIT 1 ) FROM category AS c) AS c_d
  3. JOIN news AS n ON ( ( n.add_date <= c_d.add_date OR c_d.add_date IS NULL) AND n.category_id = c_d.id )


To chyba powinno realizować to, co nie zmienia faktu, że nie widzę sensu w stosowaniu tego, bo albo ktoś przeczyta komentarz co to robi, albo spędzi dłuższą chwilę analizując o co chodziło autorowi.
Zbłąkany
Yyy sedziwoj dzięki, że czytasz moje głupoty czasem winksmiley.jpg Faktycznie zapomniałem o warunkach złączenia tongue.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.