Select unikátních záznamů podle nejvyšší hodnoty sloupce

Peter

Ahoj, v tabulke mam nejake data vid obrazok 1. Potreboval by som selectom ziskat pre kazdeho hraca zaznam, ktory obsahuje najvyssie skore. Ak hrac pre dany rok ma v jednom zazname skore 20 a v druhom 40, pouzije sa zaznam so skore 40. Tiez by som potreboval aby vysledky boli unikatne pre kazdeho hraca, teda ak su 2 zaznamy so skore 0, pouzije sa len jeden, akykolvek z nich.

Skusal som tento query:
Kód: [Vybrat]
select ps.*
from player_score ps
where ps.created_at >= '2000-01-01'
and ps.score = (select max(ps2.score)
from player_score ps2
where ps2.created_at >= '2000-01-01' and
ps2.player_id = ps.player_id
);

ale dostal som duplikatny zaznam pre hraca 4, vid obrazok 2.

Viete mi prosim poradit ako to opravit bez distinct? Dakujem



« Poslední změna: 09. 11. 2018, 20:31:34 od Petr Krčmář »


Peter

Re:Select unikatnych zaznamov podla najvyssej hodnoty v stlpci
« Odpověď #1 kdy: 09. 11. 2018, 19:37:52 »
este so zabudol doplnit, ze vo vysledku by nemala byt hodnota agregacnej funkcie

mailo9

Re:Select unikatnych zaznamov podla najvyssej hodnoty v stlpci
« Odpověď #2 kdy: 09. 11. 2018, 19:56:56 »
Ako najjednoduchsie riesenie ma napada pouzitie WITH klauzule spolu v kombinacii s window function row_number() vid. http://www.postgresqltutorial.com/postgresql-row_number/ a nasledny select where row_number = 1

Re:Select unikátních záznamů podle nejvyšší hodnoty sloupce
« Odpověď #3 kdy: 09. 11. 2018, 21:35:52 »
Pokud to chcete postaru, bez WITH nebo window funkcí, použijte pro „setřesení“ těch vícenásobných záznamů do jednoho GROUP BY a nějakou agregační funkci, která vám z těch vícenásobných záznamů vybere ten správný. Pokud chcete vybírat např. nejmladší záznam a víte, že nikdy nebudou dvě nejvyšší skóre jednoho hráče ve stejný den, můžete vzít maximum z data. A nebo pokud předpokládáte, že se záznamy do databáze vkládají chronologicky a ID se přiděluje ze sekvence, můžete použít maximální id.

Kód: [Vybrat]
SELECT ps.*
FROM player_score ps
WHERE ps.id IN (
  SELECT MAX(id)
  FROM player_score ps2
  WHERE ps2.created_at >= '2000-01-01' AND ps2.score = (
    SELECT MAX(ps3.score)
    FROM player_score ps3
    WHERE ps3.player_id = ps2.player_id AND ps3.created_at >= '2000-01-01'
  )
  GROUP BY ps2.player_id 
)

No a nebo pokud je vám jedno, který ze záznamů se vrátí u těch vícenásobných maximálních skóre, a používáte MySQL, která se pro vracení náhodných dat náramně hodí, udělejte prostě na tom vnějším SELECTu GROUP BY player_id – MySQL do výsledné sady sama náhodně vybere jeden z těch vícenásobných záznamů:

Kód: [Vybrat]
SELECT ps2.*
FROM player_score ps2
WHERE ps2.created_at >= '2000-01-01' AND ps2.score = (
  SELECT MAX(ps3.score)
  FROM player_score ps3
  WHERE ps3.player_id = ps2.player_id AND ps3.created_at >= '2000-01-01'
)
GROUP BY ps2.player_id 

El Monkey Misterio

Re:Select unikátních záznamů podle nejvyšší hodnoty sloupce
« Odpověď #4 kdy: 09. 11. 2018, 21:56:49 »
Kód: [Vybrat]
select
  id,
  player_id,
  score,
  created_at
from (
  select
    t.*,
    rank() over (partition by t.player_id order by t.score desc, t.id) as score_rank
  from t
  where t.created_at >= '2000-01-01'
  )
where score_rank = 1