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

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í".

Vložit komentář

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:

avatar © 2005-2018 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.