Sečtení X nejvyšších hodnot

Username
Člen | 36
+
0
-

Ahoj,

prosím o pomoc s následujícím problémem. Mám tabulku v MySQL:

<?php
CREATE TABLE `pokus` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `znak` varchar(2) COLLATE utf8_czech_ci NOT NULL, `cislo` tinyint(2) unsigned NOT NULL,
  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
INSERT INTO `pokus` (`id`, `znak`, `cislo`) VALUES (1, 'a', 1), (2, 'b', 1), (3, 'a', 2), (4, 'b', 2), (5, 'a', 3), (6, 'b', 3), (7, 'a', 4), (8, 'b', 4), (9, 'a', 5), (10, 'b', 5), (11, 'a', 6), (12, 'b', 6), (13, 'a', 7), (14, 'b', 7), (15, 'a', 8), (16, 'b', 8), (17, 'a', 9), (18, 'b', 9), (19, 'a', 10), (20, 'b', 10);
?>

Chtěl bych vybrat 5 řádku s nejvyšší hodnotou ve sloupci cislo a sečíst je, pro každou hodnotu ve sloupci znak. Výsledek by měl vypadat a, 40, b, 40. hledal jsem řešení v různých diskuzích, co mi našel Google, ale většinou jsem se dočetl, že MySQL to neumí, což mi přijde divné.

Díky za pomoc

nightfish
Člen | 472
+
0
-

Třeba takhle:

SELECT t.znak, SUM(t.cislo) FROM (SELECT znak, cislo FROM pokus ORDER BY cislo DESC LIMIT 5) t GROUP BY t.znak
Username
Člen | 36
+
0
-

to vrátí a 27, b 19 zkoušel jsem i LIMIT 1,5 ale nespočítá se to správně

Kori
Člen | 73
+
0
-

Musis vybrat max pocet hodnot za kazdy znak, tohle ti vrati spravny vysledek

SELECT znak, SUM(cislo) FROM (
(SELECT znak, cislo FROM pokus WHERE znak = 'a' ORDER BY cislo DESC LIMIT 5)
UNION
(SELECT znak, cislo FROM pokus WHERE znak = 'b' ORDER BY cislo DESC LIMIT 5)
) AS p2
GROUP BY znak

Editoval Kori (3. 12. 2017 3:22)

Username
Člen | 36
+
0
-

Děkuju, funguje. Co když nevím jaké hodnoty jsou ve sloupci znak? Jak budu plnit WHERE? Zplácal jsem tento dotaz, ale zase nevím jak tam nacpat podmínku na 5 nejvyšších hodnot pro každou hodnotu ve sloupci znak.

<?php
SELECT p.znak, s.sum_cislo FROM pokus p
JOIN (SELECT znak, SUM(cislo) AS sum_cislo FROM pokus GROUP BY znak) s
ON p.znak = s.znak
GROUP BY znak;
?>

Kori napsal(a):

Musis vybrat max pocet hodnot za kazdy znak, tohle ti vrati spravny vysledek

SELECT znak, SUM(cislo) FROM (
(SELECT znak, cislo FROM pokus WHERE znak = 'a' ORDER BY cislo DESC LIMIT 5)
UNION
(SELECT znak, cislo FROM pokus WHERE znak = 'b' ORDER BY cislo DESC LIMIT 5)
) AS p2
GROUP BY znak

Editoval Username (3. 12. 2017 16:49)

Kori
Člen | 73
+
0
-

Pokud to chces v jednom query, tak jedine napsat selecty s limitem za vsechny mozne kombinace. Dalsi moznosti je poskladat query programove (2 query) a nebo si napsat proceduru.

Editoval Kori (3. 12. 2017 18:44)

Username
Člen | 36
+
0
-

Tak proceduru jsem nakonec zavrhl, protože bych měl rád logiku jen na jednom místě. Pokusil jsem se udělat metodu, která zdá se funguje, zatím ji mám v Presenteru, ale pak ji přesunu do Modelu. Chtěl bych se zeptat.

  1. Je metoda takto správně, nebo jsem něco nedomyslel a šlo by to udělat lépe?
  2. Dá se druhý dotaz do databáze přepsat na Nette Database?
<?php
public function renderDefault()
{
$znaky = $this->database->table('pokus')
->select('znak')
->group('znak');

foreach ($znaky as $znak) {
$top5[] = $this->database->query('SELECT znak, SUM(cislo) AS celkem FROM (SELECT znak, cislo FROM pokus WHERE znak = ? ORDER BY cislo DESC LIMIT 5) AS p2', $znak->znak)
->fetch();
}

$this->template->top5 = $top5;
}
?>

Díky za pomoc