Průměrná cena v období
Školení, která pořádám
Představte si, že se cena nějaké služby může měnit v čase (je uložena v tabulce ceny (zacatek date, konec date, cena int)
) a nás zajímá průměrná cena v určitém období. První nápad na řešení této úlohy v podobě SELECT AVG(cena) FROM ceny
nepovede ke správnému výsledku, protože nezohledňuje délku jednotlivých období. Jednotlivé ceny musíme totiž zvážit délkou období, ve kterém platí: SELECT SUM(DATEDIFF(konec, zacatek) * cena) / SUM(DATEDIFF(konec, zacatek)) FROM ceny
– cena se vynásobí počtem dní, kdy platí, a součet těchto násobků se vydělí celkovým počtem dnů (dotaz počítá s tím, že ve sloupci konec
je uložen první den, kdy zadaná cena už neplatí).
Co když nás průměrná cena zajímá jen v období <@od, @do)
? V tom případě stačí vybrat záznamy, u kterých se období překrývá s požadovaným, a do počtu dnů započítat jen ty v požadovaném období: SELECT SUM(DATEDIFF(LEAST(@do, konec), GREATEST(@od, zacatek)) * cena) / SUM(DATEDIFF(LEAST(@do, konec), GREATEST(@od, zacatek))) FROM ceny WHERE konec > @od AND zacatek < @do
.
Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.
Diskuse
p:
s těmi proměnnými @od a @do skutečně pracujete nebo je to jen pomůcka pro zobrazeni? já bych takový dotaz komplikovaně generoval, ale asi předem si to nastavit by mělo své výhody
V PHP obvykle používám spíš PHP proměnné. Kód je psán nicméně tak, aby se dal snadno vyzkoušet třeba i z MySQL konzole.
Dost zajimave reseni, ja bych to resil daleko sloziteji. Clovek se porad uci :-)
Nápad se mi líbí, díky, ale neporozumněl jsem smyslu po prvním přečtení(možná zrovna nemám den, ale budiž). Polovina prvního odstavce by si dle mého názoru zasloužila větší "polopatičnost" :) .
proč dotaz zatěžovat dvěma zbytečnými funkcemi LEAST a GREATEST? to ten $od, $do zadává uživatel? A pokud ano, není lepší zajistit, že $od bude vždy menší a $do větší před spuštěním dotazu (třeba jejich záměnou, pokud tomu tak není)?
Ano, @od a @do zadává uživatel, proto to jsou proměnné. Funkcemi LEAST a GREATEST je neporovnávám mezi sebou, ale s daty v databázi, tudíž to nelze provést před spuštěním dotazu.
když to má být v intervalu <od,do), neměl by dotaz končit na
...WHERE zacatek >= @od AND konec < @do
?
Vzhledem k uloženým hodnotám dat nikoliv: "dotaz počítá s tím, že ve sloupci konec je uložen první den, kdy zadaná cena už neplatí".
Diskuse je zrušena z důvodu spamu.