Šta je novo?

MySQL upiti - medijana, skjunis i kurtozis

Psyche

Slavan
Učlanjen(a)
02.07.2005
Poruke
56
Poena
309
Pozdrav,
Pokusavam da u web aplikaciju koju pravim implementiram i nesto od statistike onakve kakvu je ima SPSS i da nad sadrzajem iz baze pravim raznorazne proracune.

Uglavnom, trebaju mi raspon (minimalna i maksimalna vrednost), prosek, standardna devijacija, medijana, skjunis i kurtozis.

Elem, za prve tri MySQL ima predefinisane funkcije te to nije problem. Medjutim, za medijanu, sk i ku nikako da pronadjem adekvatno resenje mada sam dosta svrljala po netu. Naleteh na neke korisnicke funkcije koje sadrze stosta interesantno ali su podrzane od strane verzije 4.0 i nize sto meni ne odgovara, a ne znam ni kako bih ih dodala listi standardnih funkcija.

Stoga pomoc. U prilogu imate formule za sk i ku, onakve kakve postoje u SPSS - a medijana je vrednost koja zauzima ono mesto u raspodeli koje deli dati niz na donju i gornju polovinu.

Npr. ako je sortiran niz: 1 3 4 5 6 - medijana je 4 i nalazi se na trecem mestu (n+1)/2.

ili za paran broj slucajeva 1 3 6 9 9 9 - medijana je 7.5 jer se nalazi na pola puta izmedju treceg i cetvrtog clana.


Zasto ovo vraca gresku:

Kod:
ROUND( SUM( POW( num_correct - AVG( num_correct ), 3) ) / ( ( COUNT( * ) - 1 ) * POW( STD( num_correct), 3) ), 3) AS skjunis, 
ROUND( ( SUM( POW( num_correct - AVG( num_correct ), 4) ) / ( ( COUNT( * ) - 1 ) * POW( STD( num_correct), 4) ) ) - 3), 3) AS kurtozis,

Warning: mysql_result(): supplied argument is not a valid MySQL result resource

dok ovo radi
Kod:
ROUND( SQRT( SUM( POW( num_correct, 2 ) ) / COUNT( * ) - POW( AVG( num_correct ), 2 ) ), 3 ) AS devijacija

mada se isto dobija prosto funkcijom STD, ali eto cisto ilustracije radi.
 

Prilozi

  • sk.gif
    sk.gif
    3 KB · Pregleda: 78
Jedno od resenja za medijanu glasi:

Kod:
$sql0 = mysql_query ("
DROP TABLE IF EXISTS tmp;
");

$sql1 = mysql_query ("
CREATE TEMPORARY TABLE tmp (
n INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
num_correct VARCHAR(99) NOT NULL );
");

$sql2 = mysql_query ("
INSERT INTO tmp (num_correct)
SELECT num_correct FROM nq_stats ORDER BY 1;
");

$sql3 = mysql_query ("
SELECT @count := COUNT(*) FROM tmp;
");

$mdn = mysql_query ("
SELECT DISTINCT num_correct AS medijana FROM tmp
WHERE n IN (FLOOR((@count+1)/2), CEIL((@count+1)/2));
");

$sql4 = mysql_query ("
DROP TEMPORARY TABLE tmp;
");

Mene inteseruje, moram li da pisem ovako ili se ovi blokovi upita mogu sabiti u jedan. Takodje, kako da isprintam resenje na sa tri decimalna mesta bez obzira na to sto je izlaz uvek ili ceo broj ili ceo i pola.

mysql_result($mdn, 0, 'medijana')
 
Primetila sam da za tacno resenje linija

Kod:
SELECT DISTINCT num_correct AS medijana FROM tmp

treba da predje u

Kod:
SELECT DISTINCT AVG( num_correct ) AS medijana FROM tmp


Elem, i dalje mi nije jasno zasto ovo nije OK:

Kod:
ROUND( SUM( POW( ( num_correct - AVG( num_correct ) ), 3 ) )  / ( ( COUNT( * ) - 1 ) * POW( STD( num_correct ), 3 ) ), 3 ) AS skjunis,
ROUND( ( SUM( POW( ( num_correct - AVG( num_correct ) ), 4 ) )  / ( ( COUNT( * ) - 1 ) * POW( STD( num_correct ), 4) ) - 3 ), 3 ) AS kurtozis

Problem je funkcija SUM, koja kad se izbaci iz upita omogucava da se dobije neki, ali za mene neupotrebljiv broj.

Zar se ne mogu sabirati kubovi izraza u kojima se vec koristi neka funkcija :smash:
 
Poslednja izmena:
Nista, uhvatih ovo promenjivom pa vratih u query.

Evo resenja za deskriptivne statistike ako nekome zatreba:

Kod:
$parametri = mysql_query ("
SELECT 
MIN( num_correct  ) AS minimum,  
MAX( num_correct  ) AS maksimum,  
ROUND( AVG( num_correct ), 3) AS prosek,  
ROUND( STD( num_correct ), 3 ) AS devijacija
FROM nq_Stats
");

$as = mysql_result($parametri, 0, 'prosek');

$sk = mysql_query ("
SELECT 
ROUND( SUM( POW( ( num_correct - $as ), 3 ) )  / ( ( COUNT( * ) - 1 ) * POW( STD( num_correct ), 3 ) ), 3 ) AS skjunis,
ROUND( ( SUM( POW( ( num_correct - $as ), 4 ) ) / ( ( COUNT( * ) - 1 ) * POW( STD( num_correct ), 4) ) - 3 ), 3 ) AS kurtozis
FROM nq_Stats
");


Ako neko zna bolje/lepse neka vice :d
 
Vrh Dno