Autor Zpráva
pajadvorak
Profil
Mám tento dotaz níže a mám potíž dostat z něj správná data.
SELECT kod, polozka_kod_sklad, material, sum(ks) as celkem FROM `fak_mat` WHERE datum BETWEEN '2018-01-01' AND '2018-12-31' GROUP BY kod order by celkem DESC limit 100

Problém spočívá v tom, že mám např. řádek kod = 123456 a pak mám další řádek kod = abcd a polozka_kod_sklad = 123456. A v těchto případech, kdy se polozka_kod_sklad = kod, tak potřebuji, aby to bylo ve stejném GROUP BY.

Potřebuji, aby to sečetlo všechny ks, kde je kod (123456) + kod=polozka_kod_sklad(123456) a seskupilo to do jednoho výsledku. Doufám, že jsem to napsal dostatečně srozumitelně.

Moc děkuji za pomoc.
Keeehi
Profil
Moc srozumitelné mi to nepřijde ale snad jsem to pochopil. Pro jistotu příklad (sloupce kod, polozka_kod_sklad, ks):
111 | ttt | 4
abc | uuu | 2
zzz | 111 | 3

Výsledek by v tomto případě měl být asi
111 | 7
abc | 2

Jenže teď přichází problém, co když v tabulce bude ještě jeden řádek
111 | ttt | 4
abc | uuu | 2
zzz | 111 | 3
eee | zzz | 11

Jaký má být výsledek teď?
pajadvorak
Profil
Keeehi:

1
v pořádku


2
takový případ není

v 1. sloupci je vždy unikátní zápis


Doufám, že teď je to jasné. Děkuji.
Kajman
Profil
Místo upřesnění vnášíte další nejasnosti. Pokud tam jsou unikátní hodnoty, tak group by nad ním není potřeba.
pajadvorak
Profil
Kajman:
Tak to zkusím takto:

123456 | | 2
abcde | 123456 | 3
haloo | sdfdsf | 1
dsfsaml | 123456 | 10

výsledek dotazu
123456 | 15
haloo | 1
Kajman
Profil
Nejvhodnější by bylo použít rekurzivní dotaz, ty umí mysql od verze 8 nebo mariadb od verze 10.2.

Pokud tam je maximálně jedno zanoření a první sloupec je jedinečný, tak bych na starých verzích zkusil něco jako

SELECT Coalesce(rodic.kod, fm.kod) kod, 
       Sum(fm.ks)                  celkem 
FROM   `fak_mat` fm 
       LEFT JOIN `fak_mat` rodic 
              ON fm.polozka_kod_sklad = rodic.kod 
                 AND rodic.datum BETWEEN '2018-01-01' AND '2018-12-31' 
WHERE  fm.datum BETWEEN '2018-01-01' AND '2018-12-31' 
GROUP  BY Coalesce(rodic.kod, fm.kod) 
ORDER  BY celkem DESC 
LIMIT  100   

Kde můžete vypustit podmínku na datum v left joinu, pokud se má hledat rodič bez omezení data.
pajadvorak
Profil
Kajman:
To vypadá zajímavě. Dotaz však trvá 26 vteřin a výsledky jsou moc veliké. Takže to nebere v potaz datum, ale počítá to kompletně z celé tabulky. Nezdá se mi, že by to bylo špatně. Vidíte tam nějakou chybu, co bych měl upravit, aby to vzalo pouze rok 2018? Děkuji
Kajman
Profil
Jaká je struktura tabulky včetně indexů? Jaký je explain toho dotazu? Co vypíše dotaz
select count(*) from `fak_mat` group by kod order by 1 desc limit 1
?
pajadvorak
Profil
Kajman:

struktura
photos.app.goo..gl/kPmFhrdmJgmxiEFR9 (smazat 1 / 2 tečky - nevěděl jsem jak to sem nejlépe vložit a obrázek je nejpřehlednější)

explain
id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra     
1     SIMPLE     fm     range     datum     datum     4     NULL     69811     Using index condition; Using temporary; Using file...
1     SIMPLE     rodic     ref     kod,datum     kod     46     elektrahkcz.fm.polozka_kod_sklad     27     Using where

count = 98241
Kajman
Profil
Evidentně nejsou hodnoty ve sloupci kod (tedy první sloupec z příkladů) unikátní.

Na strukturu je nejjednoduší příkaz
show create table ...
Kajman
Profil
Tento dotaz by mohl být imunní vůču opakujícím se hodnotám ve sloupci kod. Ale podmínka maximálního zanoření jedné úrovně platí.
SELECT Coalesce(rodic.kod, fm.kod) kod,
       Sum(fm.ks)                  celkem
FROM   `fak_mat` fm
       LEFT JOIN (SELECT DISTINCT fm2.kod
                  FROM   `fak_mat` fm2
                  WHERE  fm2.datum BETWEEN '2018-01-01' AND '2018-12-31') rodic
              ON fm.polozka_kod_sklad = rodic.kod
WHERE  fm.datum BETWEEN '2018-01-01' AND '2018-12-31'
GROUP  BY Coalesce(rodic.kod, fm.kod)
ORDER  BY celkem DESC
LIMIT  100
pajadvorak
Profil
Kajman:
Děkuji moc. Vypadá to, že vše funguje správně.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0