PDA

Pogčedajte punu verziju : Kako izračunati verižne indekse (statistika) u MySQL


misko_
12. 09. 2011., 14:00
Cao,

Racimo da imam bazu (ime joj test) gdje su podaci:
ID VALUE
1 50
2 30
3 40

i ako učinim
SELECT value from test
dobijem
50
30
40

ono što bih ja želio je sada u stupcu pored imati verižne idekse
Verižni indeks se računa kao (trenutna vrijenost razdoblja / predhodna vrijenost razdoblja) * 100 - 100

Što znaći da bi za ove podatke to trebalo biti
50
30 -40
40 33,33

U nizu verižni indeks se za prvi ne može izračunati, jer ne postoji predhodna vrijednost (zato je prva ćelčija kod drugog stupa prazna.

Ja neznam kako da to učinim.
Pa molim pomoć :-)

Hvala

japan
12. 09. 2011., 14:53
evo, na brzinu, verovatno moze i da se optimizuje...
select id, value, 100 * value / (select value from test where id = (select max(id) from test where id < t.id)) - 100 vi from test t;
+------+-------+----------+
| id | value | vi |
+------+-------+----------+
| 1 | 50 | NULL |
| 2 | 30 | -40.0000 |
| 3 | 40 | 33.3333 |
+------+-------+----------+

jablan
12. 09. 2011., 15:09
Uz pomoć JOIN-ova:


select t1.id, t1.value, t2.id, (100.0 * t1.value / t2.value) - 100
from test t1
left join test t2 on t2.id < t1.id
left join test t3 on t3.id < t1.id and t2.id < t3.id
where t3.id is null
group by t1.id, t1.value, t2.id, t2.value;

id | value | id | ?column?
----+-------+----+----------------------
1 | 50 | |
2 | 30 | 1 | -40.0000000000000000
3 | 40 | 2 | 33.3333333333333333
(3 rows)

webarto
12. 09. 2011., 15:21
Ja glasam za jablanov JOIN :P

misko_
12. 09. 2011., 15:35
Hvala na odgovorima.

Da li mi možete preporučiti neke članke, stranice, knjige koje bi me naučile pisati ovakve SQL upite.

Jer da budem iskren, pogotovo ovaj sa JOIN-ovma, ja jako teško razumjem.

jablan
12. 09. 2011., 16:18
Hm, ja konkretno nemam ništa konkretno za preporuku pošto sam sve ovo pohvatao radeći. Možda ovo nije loš intro za join-ove:

http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

U suštini, moje rešenje svodi se na to da se tabela JOINuje sa samom sobom da bi se, za svaki record dobili svi recordi sa manjim id-jem (nazovimo sve takve parove [IDa, IDb], IDa > IDb), plus još jedan join kojim se iz prvog joina eliminišu svi parovi [IDa, IDb] gde postoji IDc koji je između IDa i IDb (tako da ostaju samo uzastopni parovi u konačnom upitu).

jablan
12. 09. 2011., 19:29
^ Evo ovde malo duže objašnjenje, možda još nekom bude od koristi:

http://jablan.radioni.ca/post/10128857773/matching-successive-records-using-self-join

misko_
14. 09. 2011., 12:32
Hvala na odgovorima.

Linkovi su pomogli, malo bolje kužim, ali ipak ne dovoljno da bih takvo što sam napravio:-(, ali sigurno ću pohvatati sa vremenom.

Primjer baze koji sam ovdije napravio je pojednosavljenje mog stvarnog problema.

Moja stvarna baza je definirana ovako:

CREATE TABLE IF NOT EXISTS `lbma_gold` (
`ID` int(11) NOT NULL auto_increment,
`Date` date NOT NULL,
`usd_am` float,
`usd_pm` float,
`gbp_am` float,
`gbp_pm` float,
`eur_am` float,
`eur_pm` float,
PRIMARY KEY (`ID`),
UNIQUE KEY `Date` (`Date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;


Svaki redak ima 6 cijena, od toga ne mora svaka cijena biti prisutna. Npr,. za eur počinju tek od 1990 godine.

Jedan od upita na kojem sada radim je:

SELECT YEAR(date), ROUND(AVG(eur_pm),2) as EUR_PM
FROM lbma_gold
WHERE date BETWEEN '1999-1-1' AND NOW()
GROUP BY YEAR(date);


I sa njim dobijem:

1999, 261.37
2000, 302.64
2001, 302.80
2002, 328.05
2003, 321.25
2004, 329.06
2005, 358.32
2006, 480.52
2007, 506.83
2008, 593.08
2009, 696.92
2010, 925.11


Znači sa njim dobijem prosječnu cijenu po godini, mislim da je ovo jasno.
Ono što bi ja želio je da imam i verižni indeks pored.

Sada kada u ovaj upit pokušam ubaciti riješenje od jablana, tu zapinjem.
Pokušam već 1h ali bez uspijeha, i što je najgore ne kužim gdje griješim ni što radim.

Ako može još dodatne pomoći...
Ako treba, pošaljem ja i cijelu bazu.

jablan
14. 09. 2011., 12:53
Verovatno bi bilo zgodno da od ovog tvog queryja napraviš VIEW, pa da onda radiš nad njim indekse.