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.

Jakub Vrána, Řešení problému, 25.5.2007, diskuse: 8 (nové: 0)

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

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL: Reakce na: p

ikona Jakub Vrána OpenID:

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.

Antema:

Dost zajimave reseni, ja bych to resil daleko sloziteji. Clovek se porad uci :-)

ikona D1ce:

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" :) .

bmf:

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í)?

ikona Jakub Vrána OpenID:

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.

ikona náhradní autodíl:

když to má být v intervalu <od,do), neměl by dotaz končit na
...WHERE zacatek >= @od AND konec < @do
?

ikona Jakub Vrána OpenID:

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í".
avatar © 2005-2020 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.