Vedle se rozebírá zajímavé téma o databázích. Měl bych tu tedy jednu pěknou úlohu.
Mám tabulku s články: posts.
Ke každému článku jsou komentáře: discuss (vazba discuss.id_post=posts.id).
Jak napsat SQL abych vytáhl 200článků, a ke každému článku deset komentářů seřazených podle jména titulku toho komentáře?
Typ databáze neuvádím schválně.
Pouzit v tabulke posts row_num() a join kde je row_num mensi 11?
Ukázka úlohy TOP n pro každou skupinu - je to dobrá úloha pro cvičení - čistě relačně ve starém SQL 86 by to možná šlo přes selfjoiny - a spíš by to připomínalo IQ test. Proto už se takové úlohy řeší nerelečním aparátem v SQL - např. window funkcemi, případně lateral joinem a limitem - viz např. článek https://www.root.cz/clanky/budte-moderni-v-sql/ .
Pokud databáze implementuje ANSI SQL 2003, 2008 nebo má obdobnou funkcionalitu - nejstarším možným způsobem je korelovaný poddotaz s LIMITem - dnes se to dá udělat čitelněji a čistým ANSI SQL.
SELECT id_clanek FROM clanky LIMIT 200 - vytahne 200 clanku, idecka
Tim druhym si ale nejsem jisty, to ani rozepisovat nejdu. Melo by to byt neco s GROUP BY a COUNT.
Pro kazde id_clanek vypsat vsechny komentare. Ocislovat je COUNTem, pokud maji stejne id_clanek. A potom pomoci where vybrat vsechny, ktere maji count<10. Tohle budou asi SELECTY v sobe.
A jako jeden dotaz by slo o 3 SELECTY.
Jinak, asi moderni db na to maji nejspis 1 prikaz, jen ten neznam.
Citace od: peter kdy 17. 09. 2018, 09:45:06
SELECT id_clanek FROM clanky LIMIT 200 - vytahne 200 clanku, idecka
Tim druhym si ale nejsem jisty, to ani rozepisovat nejdu. Melo by to byt neco s GROUP BY a COUNT.
Pro kazde id_clanek vypsat vsechny komentare. Ocislovat je COUNTem, pokud maji stejne id_clanek. A potom pomoci where vybrat vsechny, ktere maji count<10. Tohle budou asi SELECTY v sobe.
A jako jeden dotaz by slo o 3 SELECTY.
Jinak, asi moderni db na to maji nejspis 1 prikaz, jen ten neznam.
S lateral joinem je to primitivní
SELECT *
FROM posts,
LATERAL (SELECT *
FROM discuss
WHERE discuss.id_post=posts.id
ORDER BY discuss.title
LIMIT 10) x
LIMIT 200
Citace od: Pavel Stěhule kdy 17. 09. 2018, 10:37:19
S lateral joinem je to primitivní
Žel s MySQL má člověk smůlu. Sice tam jsou nějaké náznaky window funkcí, ale mě to nefachalo.
Citace od: BoneFlute kdy 17. 09. 2018, 12:13:43
Citace od: Pavel Stěhule kdy 17. 09. 2018, 10:37:19
S lateral joinem je to primitivní
Žel s MySQL má člověk smůlu. Sice tam jsou nějaké náznaky window funkcí, ale mě to nefachalo.
ved ti to napisali hore, ze sa to da cez row_number ...
SELECT *
FROM posts ps
left join (SELECT title,
id_post,
ROW_NUMBER() OVER(PARTITION BY id_post ORDER BY title) AS rn
FROM discuss
) dis ON dis.id_post = ps.id
AND rn < 11
ORDER BY ps.id, ps.rn
LIMIT 200
Citace od: Peter kdy 17. 09. 2018, 12:56:49
Citace od: BoneFlute kdy 17. 09. 2018, 12:13:43
Citace od: Pavel Stěhule kdy 17. 09. 2018, 10:37:19
S lateral joinem je to primitivní
Žel s MySQL má člověk smůlu. Sice tam jsou nějaké náznaky window funkcí, ale mě to nefachalo.
ved ti to napisali hore, ze sa to da cez row_number ...
No jo no, mám MariaDB 10.1.18, a window funkce jsou až od 10.2. To bude tím.
reseni: nebud linej, pouzi bash, pouzi while cykly a if podminky, docasne data.
vyreseni bude biznisovo funkcni)
(a k lidem co chteji vse v sql: bude machri a udelejte hloubkovou deailnou analyzu a modifikaci dat pres slq.... nedokazete)
MS SQL 2008 cez ROW_NUMBER()