IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Dotaz na nejlepší výkon v tabulce sportovních výkonů

V předchozím kvízu, Online test znalostí SQL a databází, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Eda Vyskoč
Člen
Avatar
Eda Vyskoč:25.10.2018 8:20

Mám následující data v tabulce:

jmeno|prijmeni |cas |rocnik |kategorie |oddil |pohlavi |

David Alžběta 11:22 2012 Muži A Lukov Oil M
David Alžběta 10:22 2014 Muži A Lukov Oil M
Radek Lavina 13:20 2015 Muži B Kolov M
Radek Lavina 15:20 2018 Muži B Kolov M

Výsledek chci následující:

David Alžběta 10:22 2014 Muži A Lukov Oil M
Radek Lavina 13:20 2015 Muži B Kolov M

To znamená - unikátní jméno + přijmení a seřazení dle nejlepších časů!

Zkusil jsem: Zkoušel jsem tohle:

SELECT SQL_CALC_FOUND_ROWS prijmeni as prijmeni, jmeno, MIN(cas), kategorie, oddil, pohlavi, rocnik FROM table GROUP BY jmeno, prijmeni ORDER BY MIN(cas) ASC

Bohužel tohle mi vrací toto:

David Alžběta 10:22 2012 Muži A Lukov Oil M
Radek Lavina 13:20 2015 Muži B Kolov M

To jest - špatný ročník, kdyby se změnil tým a pohlaví, tak se zobrazí taky špatné! :-(

 
Odpovědět
25.10.2018 8:20
Avatar
Odpovídá na Eda Vyskoč
Michal Štěpánek:25.10.2018 10:13

a co takhle?

SELECT jmeno + ' ' + prijmeni as clovek, cas, rocnik, kategorie, oddil, pohlavi FROM table ORDER BY cas GROUP BY clovek
Editováno 25.10.2018 10:14
Nahoru Odpovědět
25.10.2018 10:13
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na Michal Štěpánek
Eda Vyskoč:25.10.2018 10:26

Jednak špatný syntax - GROUP BY musí být pře ORDER BY a navíc je to nesmysl! :-)

 
Nahoru Odpovědět
25.10.2018 10:26
Avatar
Odpovídá na Eda Vyskoč
Michal Štěpánek:25.10.2018 10:27

A co konkrétně je na tom nesmysl?

Nahoru Odpovědět
25.10.2018 10:27
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25.10.2018 10:33

MIN(cas) tam mas, co treba
MAX(rocnik)?
Jinak pouziva data z prvniho nalezeneho radku.

 
Nahoru Odpovědět
25.10.2018 10:33
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na Michal Štěpánek
Eda Vyskoč:25.10.2018 10:33

Vrátí to jeden záznam a navíc nesmyslný! :-)

 
Nahoru Odpovědět
25.10.2018 10:33
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na Peter Mlich
Eda Vyskoč:25.10.2018 10:35

Nechci vrátit maximální ročník? Co by to mělo za smysl?! :-D Chci vědět, kdy ten týpek zaběhl nejlepší čas a v kterém to bylo roce! ;-) To je to, oč tu běží! :)

 
Nahoru Odpovědět
25.10.2018 10:35
Avatar
Odpovídá na Eda Vyskoč
Michal Štěpánek:25.10.2018 10:35

Jaký datový typ máš ten čas v tabulce?

Nahoru Odpovědět
25.10.2018 10:35
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Eda Vyskoč
Michal Štěpánek:25.10.2018 10:41

Když vynecháš to groupování a dáš tam jen řazení podle časů, tak se ti to srovná správně?

SELECT * FROM table ORDER BY cas
Editováno 25.10.2018 10:42
Nahoru Odpovědět
25.10.2018 10:41
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na Michal Štěpánek
Eda Vyskoč:25.10.2018 10:53

jistě! :-) cas = typ time

 
Nahoru Odpovědět
25.10.2018 10:53
Avatar
Odpovídá na Eda Vyskoč
Michal Štěpánek:25.10.2018 10:57

Pak ti ten dotaz co jsem psal (napsaný ve správném tvaru) musí vrátit výsledek správný

SELECT jmeno + ' ' + prijmeni as clovek, cas, rocnik FROM table GROUP BY clovek ORDER BY cas
Nahoru Odpovědět
25.10.2018 10:57
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na Michal Štěpánek
Eda Vyskoč:25.10.2018 11:30

Nikoliv. :-)

Vrátí jeden záznam a navíc zcela prázdný pole 'clovek'! :-)

Editováno 25.10.2018 11:31
 
Nahoru Odpovědět
25.10.2018 11:30
Avatar
Odpovídá na Eda Vyskoč
Michal Štěpánek:25.10.2018 11:34

V tom případě se minimálně jeden z těch sloupců jmenuje jinak, nebo do dotazu dáváš jiný znak místo té '

Nahoru Odpovědět
25.10.2018 11:34
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Michal Haňáček:25.10.2018 11:39

Proč tam pořád všichni cpete to grupování?

Předpokládal bych že hledáte něco jako:

SELECT DISTINCT jmeno + ' ' + prijmeni as clovek, cas, rocnik FROM table ORDER BY cas
Nahoru Odpovědět
25.10.2018 11:39
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
Odpovídá na Michal Haňáček
Michal Štěpánek:25.10.2018 11:44

Výsledek DISTINCT a GROUP BY je v tomto případě stejný. Otázka je, co by tu distinct udělal, kdyby byly dva stejné časy...

Nahoru Odpovědět
25.10.2018 11:44
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na Michal Štěpánek
Eda Vyskoč:25.10.2018 11:46

a nemyslíš tohle náhodou? :-)

SELECT CONCAT(jmeno, " ", prijmeni) AS clovek
 
Nahoru Odpovědět
25.10.2018 11:46
Avatar
Odpovídá na Eda Vyskoč
Michal Štěpánek:25.10.2018 11:50

Ne, myslel jsem přesně to, co jsem napsal, jen musíš napsat jednoduché uvozovky a nikoliv apostrof, nebo obrácené uvozovky

Nahoru Odpovědět
25.10.2018 11:50
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Eda Vyskoč
Člen
Avatar
Eda Vyskoč:25.10.2018 12:27

Vyzkoušel jsem tyto varianty:

SELECT jmeno + '  ' + prijmeni as clovek, cas, rocnik FROM table GROUP BY clovek ORDER BY cas
SELECT jmeno + "  " + prijmeni as clovek, cas, rocnik FROM table GROUP BY clovek ORDER BY cas
SELECT (jmeno + prijmeni) as clovek, cas, rocnik FROM table GROUP BY clovek ORDER BY cas

A vše mi vrátí stejný výsledek! :-) => jeden záznam a navíc zcela prázdný pole 'clovek'!

 
Nahoru Odpovědět
25.10.2018 12:27
Avatar
Odpovídá na Eda Vyskoč
Michal Haňáček:25.10.2018 12:29

Hoď sem screenShot co ti to vypíše, když zadáš

SELECT * FROM table
Nahoru Odpovědět
25.10.2018 12:29
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na Michal Haňáček
Eda Vyskoč:25.10.2018 12:41

David Alžběta 11:22 2012 Muži A Lukov Oil M
David Alžběta 10:22 2014 Muži A Lukov Oil M
Radek Lavina 13:20 2015 Muži B Kolov M
Radek Lavina 15:20 2018 Muži B Kolov M

 
Nahoru Odpovědět
25.10.2018 12:41
Avatar
Odpovídá na Eda Vyskoč
Michal Štěpánek:25.10.2018 15:45

A toto (když vyhodíme sloučení sloupců) ti vrátí co?

SELECT jmeno, prijmeni, cas, rocnik FROM table GROUP BY prijmeni ORDER BY cas
Nahoru Odpovědět
25.10.2018 15:45
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
don.jarducius:25.10.2018 20:44

Ahoj,
nevím, o jako SQL jde, ale myslím si, že řešení je následující

select * from vysledkyTable
inner join (SELECT jmeno+ ' '+ prijmeni Clovek, Min(Cas) MinCas from vysledkyTable group by jmeno+ ' '+ prijmeni) as preData on vysledkyTable.Jmeno+' '+vysledkyTable.Prijmeni = Predata.Clovek and vysledkyTable.Cas = Predata.cas
order by vysledkyTable.cas

samozřejmě si název tabulky přepiš podle názvu své tabulky

Editováno 25.10.2018 20:45
Nahoru Odpovědět
25.10.2018 20:44
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Odpovídá na don.jarducius
Michal Štěpánek:26.10.2018 8:34

Nepřijde ti to trošku jako, kdybys hledal vidle ve stodole tankem? Bohatě stačí na zobrazení výsledků to, co jsem psal...

Nahoru Odpovědět
26.10.2018 8:34
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Michal Štěpánek
don.jarducius:26.10.2018 21:18

Podle mě, to přesně odpovídá zadání. Chce unikátní osoby, nejlepší čas osoby, rok kdy toho času dosáhl a další data z "nejlepšího" záznamu, vždy 1 unikátní záznam osoby. Viz. dotaz a ukázkové tabulky.
Jako tank to rozhodně nevidím, tank by bylo použití kurzoru :)

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
26.10.2018 21:18
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Odpovídá na don.jarducius
Michal Štěpánek:26.10.2018 21:23

A přesně na to stačí jednoduchý select. Přijde mi naprosto zbytečné, páchat takový složitý dotaz joinováním té samé tabulky, když to vyřeší jednoduchý distinct nebo group...

Nahoru Odpovědět
26.10.2018 21:23
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Michal Štěpánek
don.jarducius:26.10.2018 21:26

Jenže distinctem ani samotným group nedosáhneš požadovaného výsledku.
Myslím si, že tady není potřeba se dohadovat... vyzkoušej si to... a uvidíš … tabulka a i data jsou jednoduchý, přepis ti nepotrvá tak dlouho...

Nahoru Odpovědět
26.10.2018 21:26
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Odpovídá na don.jarducius
Michal Štěpánek:26.10.2018 21:28

Přesně to jsem udělal a vysledek byl dle očekávání...

Nahoru Odpovědět
26.10.2018 21:28
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Michal Štěpánek
don.jarducius:26.10.2018 21:35

Ok... tvůj poslední select vypíše 4 sloupce, požadováno je 7... Někde je něco špatně...
Nehledě na to, že ten dotaz musí vyhodit chybu... jak SQL pozná, že chceš minimální čas a ne maximální, to samé ročník, to má věšteckou kouli?

Nahoru Odpovědět
26.10.2018 21:35
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Odpovídá na don.jarducius
Michal Štěpánek:26.10.2018 21:50

Není to o počtu sloupců, jen se mi to nechtělo všechno vypisovat a na nejnižší čas stačí dát MIN(cas)

Nahoru Odpovědět
26.10.2018 21:50
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Michal Štěpánek
don.jarducius:26.10.2018 22:08

Ok, super, rád se nechávám houpat, pouťové atrakce mám rád, ale ty se mnou houpeš až moc...
Co to křestní jméno a ten ročník, kdy dosáhl nejlepšího času? … zajímalo by mě, co používáš za SQL DB...

Nahoru Odpovědět
26.10.2018 22:08
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Nahoru Odpovědět
26.10.2018 22:13
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na don.jarducius
Eda Vyskoč:27.10.2018 18:14

Opravdu to nešlo jednoduchým selectem! :-)

Máš to správně, děkuji! ;-)

 
Nahoru Odpovědět
27.10.2018 18:14
Avatar
Paul
Člen
Avatar
Paul:28.10.2018 17:37

To je ideální adept na využití analytické funkce:

select * from (
select jmeno, prijmeni, cas, rocnik, katergorie, oddil, pohlavi,
rank() over (partition by jmeno, prijmeni order by cas) as je_nejlepsi_cas) a
where a.je_nejlepsi_cas = 1;
 
Nahoru Odpovědět
28.10.2018 17:37
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Eda Vyskoč
Peter Mlich:29.10.2018 8:22

Nechce se mi cist celou diskuzi nad tim. Asi i vyreseno. Ale stejne pripojim tip reseni :)
Chces udaje o cloveku? Tak je pripoj?

  • nejdriv vytrdis groupem, nechas si id zaznamu
  • a pak pres left join pripojis data

A je to presne logicky postup, jakym bys postupoval i realnem zivote. Take by sis nechal vyhledat programem nejdriv zaznamy podle kriterii (seznam id) a pak by sis je rozklikaval a prohlizel.

SELECT
   a.id, b.jmeno, b.rok
FROM
  (SELECT id FROM table ... GROUP by ... ) a
  LEFT JOIN table b ON b.id=a.id
ORDER BY ...

Pripadne s tim group tam muzes mit v select nejaku count nebo neco, co se da ziskat jen tim grupem.

Editováno 29.10.2018 8:23
 
Nahoru Odpovědět
29.10.2018 8:22
Avatar
Eda Vyskoč
Člen
Avatar
Odpovídá na Peter Mlich
Eda Vyskoč:2.11.2018 20:12

A jak bys udělal tzv. ztrátu sloupeček, tj. TIME(cas - MIN(cas)) AS ztrata? :-)

Ke každému záznamu zobrazit ztrátu, kde ztráta časová je čas závodníka mínus nejmenší čas v databázi! :-)

Díky! :-)

 
Nahoru Odpovědět
2.11.2018 20:12
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:5.11.2018 8:13

Cas by byl soucasti toho GROUP BY, jak psal don.jarducius 25. října 20:44.

 
Nahoru Odpovědět
5.11.2018 8:13
Avatar
Paul
Člen
Avatar
Odpovídá na Peter Mlich
Paul:5.11.2018 14:45
select * from (
select jmeno, prijmeni, cas, rocnik, katergorie, oddil, pohlavi, cas - (select min(cas) from tabulka) as ztrata,
rank() over (partition by jmeno, prijmeni order by cas) as je_nejlepsi_cas
from tabulka) a
where a.je_nejlepsi_cas = 1;
Editováno 5.11.2018 14:45
 
Nahoru Odpovědět
5.11.2018 14:45
Avatar
Paul
Člen
Avatar
Odpovídá na Eda Vyskoč
Paul:5.11.2018 15:42
select * from (
select jmeno, prijmeni, cas, rocnik, katergorie, oddil, pohlavi, cas - (select min(cas) from tabulka) as ztrata,
rank() over (partition by jmeno, prijmeni order by cas) as je_nejlepsi_cas
from tabulka) a
where a.je_nejlepsi_cas = 1;
 
Nahoru Odpovědět
5.11.2018 15:42
Avatar
Eda Vyskoč
Člen
Avatar
Eda Vyskoč:5.11.2018 20:25
SELECT p.jmeno AS jmeno, p.prijmeni AS prijmeni, t.cas AS cas, SEC_TO_TIME(ROUND(TIME_TO_SEC(p.cas)/3.9,0)) AS tempo, TIME_FORMAT(SEC_TO_TIME(( TIME_TO_SEC(cas) - (SELECT TIME_TO_SEC(Min(cas)) FROM prebornik) )), '%i:%s') AS ztrata, p.kategorie AS kategorie, p.oddil AS oddil, p.pohlavi AS pohlavi, p.rocnik AS rocnik FROM prebornik p INNER JOIN (SELECT prijmeni, jmeno, MIN(cas) AS cas FROM prebornik GROUP BY prijmeni, jmeno) t ON p.prijmeni = t.prijmeni AND p.jmeno = t.jmeno AND p.cas = t.cas ORDER BY t.cas ASC

MASAKR! :-D Funguje

 
Nahoru Odpovědět
5.11.2018 20:25
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 39 zpráv z 39.