Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: MySQL/PHP - Arvojen muutos

Damiqib [06.12.2007 16:02:36]

#

Minulla on SQL taulu jossa on päivittäin muuttuvia datasarakkeita parikymmentä kappaletta. Nyt pitäisi jotenkin fiksusti saada tehtyä kysely, josta saisi helposti muutokseen edelliseen päivään (tai määriteltyyn päivään) nähden (arvo/%).

MySQL:

date        data_1  data_2
2007-12-01      11      12
2007-12-02       9      13
2007-12-03      10       9

Haettu tulostus:
2007-12-03 +1 -4
2007-12-02 -2 +1
2007-12-01

En itse onnistu kehittämään muuta ratkaisua, kuin julmettu määrä erillisiä kyselyitä, jossa arvoja verrataan, joten parempaa ratkaisua kaipaisin.

Lebe80 [06.12.2007 16:21:06]

#

Jos vaan laskisit muutoksen (ts. erotus, ns. miinuslasku) ihan php:ssä taulukon edellisestä arvosta.

Simppeli for-lause, jossa käyt taulukon solut läpi ja vähennät edellisen arvon solujen arvot samalla.

ajv [06.12.2007 17:05:52]

#

Leben idea on huomattavasti parempi, mutta oli pakko kokeilla miten tuon saisi kyselyllä tehtyä :)

SELECT
	pvm,
	data1 - (SELECT data1 FROM test AS r2 WHERE r1.pvm > r2.pvm ORDER BY r2.pvm DESC LIMIT 0, 1) AS Diff1,
	data2 - (SELECT data2 FROM test AS r2 WHERE r1.pvm > r2.pvm ORDER BY r2.pvm DESC LIMIT 0, 1) AS Diff2
FROM test AS r1

Jos taulussa on id-kenttä (ja se on vielä indeksoitu), niin tuosta voi saada jopa tehokkaan, ku ei tartte alikyselyissä hakea kaikkia rivejä ja sortata, vaan voi viitata suoraan yhteen riviin: WHERE r2.id = r1.id - 1

Tulos tuolla testikyselyllä:

pvm 	Diff1 	Diff2
2007-12-01 	NULL 	NULL
2007-12-02 	-2 	1
2007-12-03 	1 	-4

Edit:

Niin ja sitten kun tuon koko roskan piilottaa näkymän taakse näin:

CREATE VIEW Datadiff AS
SELECT
	pvm,
	data1 - (SELECT data1 FROM test AS r2 WHERE r1.pvm > r2.pvm ORDER BY r2.pvm DESC LIMIT 0, 1) AS Diff1,
	data2 - (SELECT data2 FROM test AS r2 WHERE r1.pvm > r2.pvm ORDER BY r2.pvm DESC LIMIT 0, 1) AS Diff2
FROM test AS r1

Niin tuloksen saa helpon näköisesti clienttipuolella näin:

SELECT pvm, Diff1, Diff2 FROM Datadiff

En ota kantaa kuinka järkevää tämä kaikki on... :)

Edit2: Testasin indeksoitu Id versus date, dataa 2000 riviä, SQL: SELECT pvm, Diff1, Diff2 FROM Datadiff LIMIT 0, 30, tulos:
date 5.4823 s
Id: 0.0393 s

Damiqib [06.12.2007 23:41:47]

#

ajv:lle suuri kiitos.

Tuo kun on päivittäinen statistiikkataulu, ei sinne tule kuin yksi rivi päivässä lisää; id primääri ja date uniikki, joten melko vauhdilla tuo puskee dataa pihalle (nopeusero on huomattava verrattuna tuohon PHP-viritykseeni).

Hieman meinasi vain tuottaa harmaita hiuksia, kun kaikki arvot tuolla statistiikka taulussa oli UNSIGNED, ja tämän takia tuolla VIEW:ssä arvot oli ihan mitä sattuu, ei meinannut ongelma aueta mitenkään. Nyt kuitenkin toimii. Kiitoksia tästä.

ajv [07.12.2007 00:16:37]

#

Eipä kestä :) Päivitithän nuo alikyselyt käyttämään sitä id-kenttää:

SELECT data1 FROM test AS r2 WHERE WHERE r2.id = r1.id - 1

Damiqib [07.12.2007 00:36:51]

#

Jostain syystä tuo on nopeampi tuolla date::lla kuin id:llä, ero tyyliin 0.004 sekuntia jokaisella haulla daten hyväksi, mutta eipä taulussa ole vasta kuin kolme testiriviä.

Toisaalta tuo date on myös uniikki, joten onhan sekin? indeksoitu.

Vaihdoinpa nyt kuitenkin alikyselyt käyttämään tuota id-kenttää... ;)

ajv [07.12.2007 00:59:27]

#

Juu, ei sitä nopeuseroa 3 rivillä vielä huomaakkaan, mutta rivien lisääntyessä tuo id-kyselyn aika pysyy aina samana, mutta date-kyselyn aika kasvaa suoraan suhteessa siihen kuinka paljon kannassa on rivejä ja kuinka paljon näkymä-taulussa on noita alikyselyllä tehtyjä kenttiä. date-kentän indeksillä ei tässä tapauksessa ole merkitystä, koska:

SELECT data1 FROM test AS r2 WHERE r1.pvm > r2.pvm ORDER BY r2.pvm DESC LIMIT 0, 1

hakee taulusta kaikki rivit, järjestää ne päivämäärän mukaan ja antaa ulos ensimmäisen tuloksen tästä tulosjoukosta.

SELECT data1 FROM test AS r2 WHERE WHERE r2.id = r1.id - 1

hakee vain ja ainoastaan yhden rivin ja senkin aika sutjakasti, koska hakuehdossa on käytetty primary key -kenttää.

P.S. Huomaa, et oon lomalla ku jaksaa notkuu netissä auttelemas immeisiä viel tähän aikaan näinkin perusteellisilla selityksillä :)

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta