Autor Zpráva
SQLnoob
Profil *
cau, potřebuju se naučit princip, jak vytvořit v jednom dotazu, alespon 2 agregační funkce zároveň. Zkoušel jsem už hledat na googlu, ale to co asi fungovalo jiným, mě nešlo, nebo jsem našel trochu něco jiného.

Jednoduchý příklad:
1tabulka, 1 sloupec - třeba číselné hodnoty
jak udělám, abych z toho jednoho sloupce nejdřívě zjistil počet(COUNT) a pak ten COUNT sečetl(SUM)
nebo třeba zjistil unikátní hodnoty, a ty pak sečetl to je jedno
dík
juriad
Profil
Není mi jasné, co by to mělo dělat.
Součet počtů je počet všech záznamů, není třeba seskupovat.
Sečíst unikátní vyžaduje vnořený dotaz:
SELECT SUM(cislo) AS soucet
FROM (
  SELECT cislo
  FROM cisla
  GROUP BY cislo
) x
SQLnoob
Profil *
no šlo/jde mi hlavne o princip/jak se dělá ten vnořený dotaz, překvapivě to ale stejnak moc nechápu, jsem myslel že se tam někde musí použít příkaz DISTINCT. Šlo by prosím jeste napsat pro lepší pochopení, jak bys udělat z tich samých dat, prvně průměr tich čísel a pak součet tich averaglejch čísel? +k čemu je tam to x?
díky
juriad
Profil
Zkusím to popsat ze šířky.
DISTINCT můžeš považovat za speciální případ GROUP BY; je to jen zkratka.
SELECT DISTINCT a, b, c FROM tabulka
je to samé jako:
SELECT a, b, c FROM tabulka GROUP BY a, b, c
za předpokladu, že některý ze sloupců a, b, c je unikátní, stačí v GROUP BY uvést jen ten (v MySQL; obecně = v jiných DB to neprojde).

GROUP BY funguje tak, že vezme všechny řádky a vytvoří skupinky řádků, které mají stejné hodnoty ve všech sloupcích uvedených v klauzuli GROUP BY. Z každé skupinky se následně vypočítá jeden reprezentant.
Takže ten DISTINCT funguje tak, že vytvoří skupinky různých řádků. Většina skupinek bude asi mít jen jeden řádek, ale to nevadí.
Z těch, které mají řádků více, se vybere reprezentant snadno, může se vzít libovolná hodnota, protože jsou stejně všechny stejné.
Jestli nechápeš ten DISTINCT, nevadí.

Zkusme napřed počítat různá čísla podle příkladu.
Tabulka obsahuje řádky s čísly: 1, 1, 2, 3, 3, 3, 4, 5, 5.
SELECT cislo FROM cisla GROUP BY cislo
Vrátí 1, 2, 3, 4, 5. Protože vytvoří skupinky (1, 1), (2), (3, 3, 3), (4), (5, 5) a z každé vybere reprezentanta.

SELECT cislo, COUNT(*) as pocet FROM cisla GROUP BY cislo # (*)
Vrátí 1 - 2, 2 - 1, 3 - 3, 4 - 1, 5 - 2. Vrátí počet záznamů v každé skupince, což je postupně 2, 1, 3, 1, 2.
Kvězdička v tomto případě není moc důležitá; obecně tam patří název sloupce, ale protože je sloupec nutně v každém řádku.
Podobně jako COUNT funguje SUM, MIN, MAX, AVG. Ale všimni si, že pokud by tabulka obsahovala více sloupců, třeba u SUM by záleželo na tom, který sloupec se bude za skupinu sčítat.

Tím máme pokrytý základ použití GROUP BY.
Jdeme na vnořené dotazy. Píší se za FROM jakoby to byla tabulka. Uvádí se do závorek a mají povinný alias (protože musí mít nějaký název).
Tedy příklad poddotazu, který nic nedělá (jen vrátí celou tabulku) je:
SELECT * FROM (SLECT * FROM tabulka) a
To a na konci je alias - pojemování výsledku toto poddotazu.

Většinou jsou poddotazy nutné v připadě, že potřebuješ něco udělat po první agregaci. Třeba další agregaci, filtrování, připojení další tabulky.
Takže dotaz (*) použijeme jako poddotaz a budeme jen považovat za tabulku:
SELECT * FROM (SELECT cislo, COUNT(*) as pocet FROM cisla GROUP BY cislo) pocty
Teď přidáme agregaci (bez seskupení = aplikovaná na celou tabulku, nikoli po skupinkách)
SELECT SUM(pocty.cislo), SUM(pocty.pocet) FROM (SELECT cislo, COUNT(*) as pocet FROM cisla GROUP BY cislo) pocty
Tady vidíš, že jsem se odkázal na sloupec cislo a pocet, který vznikl jako počet řádek ve skupině ve vnitřním dotazu, použil agregační funkce SUM.

OK?
SQLnoob
Profil *
wow děkuju moc, to group by a DISTINCT už chápu, ty vnořený dotazy v podstatě taky, jen si stím musím trochu pohrát a pochopit tu syntaxi
díky moc :)
Kajman
Profil
A distinct jde použít i jako modifikátor v agregačních funkcích pro dotazy nebo třeba zjistil unikátní hodnoty, a ty pak sečetl

select sum(distinct cislo) soucet_jedinecnych_hodnot from cisla

U funkce sum se tento modifikátor moc často nepoužívá, u count se často používá ke zjištění počtu jedinečných hodnot.
SQLnoob
Profil *
mužu se ještě zeptat prosím, jestli se jde také nějak odkazovat na sloupce který si pojmenuju přes AS ?

Příklad:
Select ID, Prijmeni, CONCAT('nejakytext: ',ID) as prevod,
SUBSTRING(CONCAT('nejakytext: ',ID) FROM 5) * 100 AS sub
from zakaznici
(převede číselné ID do nového sloupce s textem, a pak z toho sloupce, vezmu to ID a dám ho zas do novýho sloupce) (jde mi o princip, vím že to asi nedává jinak smysl..)

když ale todle chci udělat, tak musím znova opisovat to co uz jsem jednou napsal, jde o: CONCAT('nejakytext: ',ID),
místo toho aby stačilo napsat třeba jen: SUBSTRING(prevod, FROM 5)
příde mi to neefektivní takle to dělat
Alphard
Profil
V této části dotazu není možné referencovat alias, ten je přístupný až v group, order nebo having. Souvisí to s vnitřní implementací a konzistencí.
Buď to zopakujte, nebo využijte poddotaz (vnější dotaz už normálně uvidí alias poddotazu).

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: