Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Obliczanie średniej i odchylenia standardowego
damianprz
post
Post #1





Grupa: Zarejestrowani
Postów: 41
Pomógł: 0
Dołączył: 26.08.2009
Skąd: Zamojsce

Ostrzeżenie: (0%)
-----


(IMG:http://images48.fotosik.pl/188/36eb6354103b063bm.jpg)
SCREEN

Na screenie widać prosty schemat tabeli w bazie danych
Na dole struktura a na górze rekordy
Mamy 8 dni i 4 produkty dla których trzeba policzyć Popyt średni i Odchylenie Standardowe

Kolega proponuje tak obliczać Pśr i OS
Cytat("Norbert")
$pytanko="SELECT popyt_klej FROM popyt";
$rezultat = mysql_query($pytanko)
or die("Błąd zapytania");


$tablica = mysql_fetch_array($rezultat);
$n=count($tablica);
$srednia=0;

for($i=0;$i<=$n;$i++)
{
$srednia=$srednia+$tablica[$i];
}

$srednia=$srednia/$n;

for($i=0;$i<=$n;$i++)
{
$wyraz_srednia=$tablica[$i]-$srednia; // tutaj do zmiennej $wyraz_srednia przypisujesz roznice danej liczby i sredniej wszystkich liczb

$tablica2[$i]= $wyraz_srednia * $wyraz_srednia;
}

for($i=0;$i<=$n;$i++)
{
$wynik=$wynik+$tablica2[$i]; //dostajesz sume tych wszystkich kwadratow roznicy wyrazu i sredniej;
}
$wynik=sqrt($wynik);

echo "<h1>Srednia: ".$srednia."</h1><P>";
echo "<h1>Odchylenie: ".$wynik."</h1><P>";


Kod daje takie wyniki dla popyt_klej i popyt_srubki
Srednia: 10
Odchylenie: 17.320508075689

Kod daje takie wyniki dla popyt_farba i popyt_drewno
Srednia: 5
Odchylenie: 8.6602540378444

Powinna wyjść średnia dla popyt_klej:
160/8 czyli 20

Mam takie pytanie: Czy da radę napisać tak kod aby później była możliwość dodawania kolejnych wierszy Id=9, data, popyty dla poszczególnych towarów itd... oraz możliwość dodawania towarów, czyli chodzi mi o taki kod który by liczył Pśr i OS nawet gdy tabela będzie się rozrastać w 2 wymiarach

Chyba nie ma sensu dla każdego towaru robić osobną tabelę w bazie danych. Takie rozwiązanie jakie prezentuje screen, że w jednej tabeli są wszystkie towary i wszystkie wartości popytu jest chyba najlepszy. Tylko problem z tym ciężkim do wymyślenia kodem.

Jakby ktoś był w stanie coś wymyśleć to proszę o jakieś pomysły lub kontakt
GG 3257134
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
thek
post
Post #2





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




No jasne. Zauważ, że grupujesz dane po id_towaru. Nieważne więc ile ich jest. Zawsze policzy te dane dla tylu, ile jest różnych id_towaru. Nieważne czy będzie to 3, 33 czy 3333 (IMG:style_emoticons/default/smile.gif) Oczywiście im więcej danych tym dłuższy czas obliczeń. Ale nie sądzę by nagromadziło się ich tyle by znacząco trzeba było czekać na wyniki (IMG:style_emoticons/default/winksmiley.jpg)

W tym momencie masz dorobić, jeśli dobrze zrozumiałem, tabelę przechowującą informację o danych statystycznych dla tego towaru. Czyli tabela o kolumnach:
id_towaru, średnia, odchylenie, stan

Jeśli tak, to wyliczone za każdym razem dane od razu można użyć jako UPDATE w tej nowej tabeli. Na pewno masz gdzieś dane dotyczące obecnego stanu danego produktu. Zapytanie więc pobierało by tę daną pomniejszoną o popyt z danego dnia, no chyba, że to już gdzieś automatycznie by odejmowało i stan byłby "na bieżąco".
Załóżmy, że jest tabela przechowująca stan każdego z produktów i mająca inne dane (jakaś o nazwie hmmm... Stan ? (IMG:style_emoticons/default/winksmiley.jpg) ) oraz możemy to połączyć z już obliczonymi wynikami średnimi i odchyleniami bo w końcu mamy łączącą je kolumnę id_towaru jako klucz.
  1. SELECT c.*, s.aktualny_stan FROM ( SELECT t.nazwa, p.id_towaru, avg( p.popyt ) AS srednia, std( p.popyt ) AS odchylenie FROM Produkty p LEFT JOIN Towar t ON p.id_towaru = t.id GROUP BY p.id_towaru) c LEFT JOIN Stan s ON c.id_towaru = s.id_towaru
Świetnie. Właśnie połączyliśmy wyniki ze stanem... Pozostaje jedynie zapisać je w tabeli nadzorującej co się dzieje. Niech to będzie Raport o polach jakie podałem na początku.
  1. UPDATE Raport r LEFT JOIN (tutaj walnij cale powyższe zapytanie) w ON r.id_towaru = w.id_towaru SET r.srednia = w.srednia, r.odchylenie = w.odchylenie, r.stan = w.aktualny_stan

Zauważ, że można część widoczna pod aliasem w optymalizować poprzez usuwanie z podzapytań kolumn jakie nie są nam potrzebne. A więc tak naprawdę możemy wyrzucić całkowicie łączenie z tabelą Towary (bo nie potrzebujemy w tym wypadku nazwy (IMG:style_emoticons/default/smile.gif) ) i skrócić zapytanie do:
  1. UPDATE Raport r LEFT JOIN ( SELECT p.*, s.aktualny_stan FROM ( SELECT id_towaru, avg( popyt ) AS srednia, STD( popyt ) AS odchylenie FROM Produkty GROUP BY id_towaru) p LEFT JOIN Stan s ON p.id_towaru = s.id_towaru ) w ON r.id_towaru = w.id_towaru SET r.srednia = w.srednia, r.odchylenie = w.odchylenie, r.stan = w.aktualny_stan
Przypatrz się temu zapytaniu, bo z reguły takie podejście do UPDATE wielu rekordów jednocześnie poprzez użycie LEFT JOIN by połączyć tabelę z danymi starymi i nowymi a potem nadpisanie odpowiednich kolumn wartościami innej kolumny jest czymś rzadko stosowanym, choć przydatnym, gdyż nie trzeba odwoływać się za każdym razem do jakiegoś identyfikatora w warunku WHERE, co jest najczęściej stosowana formą rozpoznawania jaki wiersz mamy uaktualniać (IMG:style_emoticons/default/smile.gif) Ja tak sobie parę dni temu zautomatyzowałem aktualizację jakichś 400-500 rekordów w bazie (IMG:style_emoticons/default/winksmiley.jpg)
Zakładam, że w nowej tabeli są już jakieś domyślne rekordy dla produktów o tym id, choćby puste. Jeśli nie to zrób INSERT i tyle (IMG:style_emoticons/default/smile.gif)
Powinniśmy po tym działaniu w tej tabeli mieć zawsze tyle rekordów ile jest produktów. Jeśli teraz będziesz chciał wyświetlić te dane to robisz:
  1. SELECT t.id, r.* FROM Raporty r LEFT JOIN Towary t ON r.id_towaru = t.id
Możesz jednak rozwiązać to nieco inaczej. Możesz dodać jeszcze dodatkową kolumnę z datą, dzięki temu zapytanie uruchomione po zakończeniu wprowadzania popytów z danego dnia stworzy rekordy w tej bazie zamiast je uaktualniać. Dzięki temu będziesz miał dane o średniej, odchyleniu i stanie dla każdego produktu z dowolnego dnia. Oczywiście jeśli już przechowujesz informację o stanie produktu na każdy dzień w innej tabeli, to nie ma sensu jej dublować także tu. Od tego posłuży ewentualny JOIN z tamtą tabelą i wyciagnięcie stanu na interesujący nas (IMG:style_emoticons/default/smile.gif) Na upartego to odpowiednio zaplanowawszy bazę można dzięki temu tworzyć raporty obejmujące określone okresy czasu. Osobiście jednak uważam, że od tego praca magisterska jest, aby samemu coś zrobić. Możesz nie wierzyć, ale ja swoją zrobiłem od A do Z samodzielnie, bo temat wybrałem sobie taki, że nie miałem szans na znalezienie gotowca w necie ("Analiza wydajnościowa technik animacji komputerowej przedstawicieli systemów operacyjnych rodziny Windows i Linux w środowisku Maya"). W przerwach zaś jednemu kolesiowi pisałem bardzo prosty CRM do jego magisterki. Nie płacił wiele to i wiele funkcji nie dostał (IMG:style_emoticons/default/winksmiley.jpg) Zresztą napisanie samemu pracy sprawi, że na obronie z Twojej pracy Cię nie zagną nawet najbardziej wrednymi pytaniami. Dla mnie najtrudniejszym było: "Jak Pan sobie wyobraża wykorzystanie tej pracy. Do czego może się ona przydać? Jak ja rozwinąć by można". A na to odpowiedź znałem od momentu gdy poznałem wyniki swoich pomiarów (IMG:style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post

Posty w temacie
- damianprz   Obliczanie średniej i odchylenia standardowego   26.08.2009, 17:47:27
- - *OuTSideR*   przy obliczaniu sredniej zmien znak <= na < ...   26.08.2009, 18:22:25
- - damianprz   I co to da? Próbowałem i nic Powyższy kod bierze ...   26.08.2009, 21:20:22
- - thek   Wartość średnia to prosta sprawa, robisz bowiem su...   26.08.2009, 22:09:38
- - damianprz   Tylko jak zrobić sumowanie wszystkich wartości w k...   26.08.2009, 22:19:13
- - thek   Sumowanie wszystkiego w kolumnie: [SQL] pobierz, p...   26.08.2009, 22:47:41
- - damianprz   [PHP] pobierz, plaintext Średnia wynosi: 10.625, a...   27.08.2009, 11:59:54
- - thek   Problemy które poruszasz w poście zaznaczyłem po o...   27.08.2009, 13:01:53
- - damianprz   Na screenie widać 3 tabelki które zrobiłem wg twoj...   27.08.2009, 15:06:49
- - thek   Bo z rozpędu nie dopisałem warunku łączenia [SQL]...   27.08.2009, 15:59:16
- - damianprz   Możesz mi sprawdzić czy to jest OK? Do wyświetlani...   27.08.2009, 16:04:56
- - thek   Kod wygląda poprawnie. W sumie chyba jedynie nie m...   27.08.2009, 20:02:28
- - damianprz   Dzięki stary za pomoc Powyższe obliczenia stosuje ...   27.08.2009, 21:46:24
- - thek   No jasne. Zauważ, że grupujesz dane po id_towaru. ...   27.08.2009, 23:38:49
- - damianprz   Oj kolego thek, co ja bym bez Ciebie zrobił Dzięk...   28.08.2009, 00:00:18
- - thek   A ja życzę powodzenia w kodzie php/html i analizie...   28.08.2009, 00:54:52
- - damianprz   Ponoć ma być raczej pod koniec września tak żeby j...   28.08.2009, 18:21:36
- - thek   Zapytanie sypie Ci błąd bo nie nadałeś aliasu dla ...   28.08.2009, 21:37:08
- - damianprz   Już wcześniej ustawiłem wartości na double z obawy...   28.08.2009, 21:53:30
- - thek   Nie dublujmy może tematów i skupmy się w jednym U...   28.08.2009, 23:31:14
- - damianprz   [PHP] pobierz, plaintext UPDATE zapasy z LEFT JOIN...   29.08.2009, 11:40:41
- - thek   Owszem Mam na laptopie swoim wszystko co potrzebn...   29.08.2009, 13:21:54
- - damianprz   Już wszystko działa! Instalka Vertrigo pomogła   29.08.2009, 13:28:35
- - thek   Widzę, ze sugestia o fatalnym wpływie MySQL 3.X na...   29.08.2009, 16:20:12
- - MMaro   Witam odkopuje temat - ponieważ mam problem z ob...   21.06.2012, 17:50:42
- - thek   Pytanie... Po co obliczać odchylenie samemu, skoro...   21.06.2012, 19:20:41


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 8.10.2025 - 05:12