Autor Zpráva
Kcko
Profil
Kazdych 5 min se mi z jiste webove sluzby bude ukladat 15 men kurzu ( EUR, RUB , JPY .. )

do tabulky
mena | kurz | datum_zapisu


Ty casy budou po 5 min sice ale ne presne zaokrouhlene , cili napr 9:02:37 | 9:07:42 | 9:13:12 atd

a klient si chce zobrazit napriklad vsechny kurzy mezi nekolika dny ci tydny i mesici a nastavit si interval ( po 30 min, po 1 h, po 2h, po 4h, po 1 dni ..)

a chce prehledny vypis

zkousel jsem si udelat sql dotaz po 30 min


select *

from rates
where date in
(select min(date) from rates
WHERE date BETWEEN '2008-3-21' AND '2008-3-22'
group by floor(unix_timestamp(date)/ (1800) )
);



a momentalne je v DB asi 4500 a je to pomale jak blazen ( 18s)


Nedokazu si predstavit ze si zvoli treba hodinovy interval a rozpeti treba 20 dnu .... to tu DB polozi.


Nevim jak to v SQL elegantne vyresit a myslim ze by se mel vymyslet nejaky zpusob jak to lepe ukladat, indexovat a z db dostat



Vedel by nekdo elegantni zpusob? Ja zacinam byt v koncich :/
nightfish
Profil
a momentalne je v DB asi 4500 a je to pomale jak blazen ( 18s)
máš index na sloupci date? pokud ne, tak honem vytvořit

ale celé se mi to zdá takové nějaké divné, určitě to půjde udělat i nějak elegantněji (i když třeba s nutností trochu překopat databázi)
Kcko
Profil
Samozrejme ze mam ...

Neco elegantniho bych uvital .. zatim me nenapada nic co by se pak dalo elegantne vyuzit pro vsechny intervaly ..
Kajman_
Profil *
Lepší db systémy umí vytvořit index i na výraz floor(unix_timestamp(date)/ (1800).

Pro denní graf může být rychlejší obrácený způsob... kdy budeš mít všechny časy půlnocí v datém intervalu a k nim najdeš vždy první záznam z téhle tabulky.

Ještě, jestli nepřidat příznaky. První v den, půlden, ... hodinu.

Ale obecné pro všechny intervaly není ani jedno z těchto řešení.
Kcko
Profil
Jake priznaky?

napr?

1800 pro prvni cas v pulhodine

3600 pro prvni cas v hodine?


predstavoval bych si asi 1 sloupecek / priznak /

kde bych zavolal where priznak = $cosi // vybere nejblizsi casy v pulhodine


dale priznak = $cosi2 // v hodine .. atd az k nejvyssimu intervalu


ale co urcit jako priznak? nejblizsi cas v pulhodine ( 00 az 30 ) je zaroven nejblizsi cas v hodine ..
Kajman_
Profil *
Možná příznaky
udajjeprvnidanyden (hodnoty null a jednou denně 1)
i
udajjeprvnivpulhodinux (hodnoty null nebo 0-47)

A ještě by mohlo být pro ty krátké intervalz rychlejší než ten group něco jako

set @nextdate='0000-00-00';
select
@nextdate:=from_unixtime(floor(unix_timestamp(date)/1800)*1800+1800) tmp,
r.*
from rates r
WHERE r.date BETWEEN '2008-3-21' AND '2008-3-22'
having r.date>=@nextdate
order by r.date
Kcko
Profil
Vypada to ze to je docela rychle, uvidime co pri velkem poctu radku, kazdopadne zatim velice dekuji, Petre ;)
Kcko
Profil
Tak ted po mensi kontrole

SET @nextdate = '0000-00-00';# MySQL vrátil prázdný výsledek (tj. nulový počet řádků).
SELECT @nextdate := from_unixtime( floor( unix_timestamp( date ) /7200 ) *7200 +7200 ) tmp, r. *
FROM cis_rates r
WHERE r.date
BETWEEN '2008-3-15'
AND '2008-3-25'
AND currency_code
IN (
'EUR', 'CZK'
)
HAVING r.date >= @nextdate
ORDER BY r.date



Jsem dostal toto

tmp id currency_code date mid_rate
2008-03-20 17:00:00 3 EUR 2008-03-20 15:29:12 25.348
2008-03-20 21:00:00 648 EUR 2008-03-20 19:04:27 27.243


Zaokrouhluje to nejak divne , zkusis se na to jeste podivat?
Kajman_
Profil *
V tom tmp je pomocný údaj, pro hledání dalšího času. Není to zaokrouhlení na tom řádku.
Kcko
Profil
Potreboval bych jeste vymyslet 2 veci


1/ zaokrouhleni aby to potom na vystupu vypadalo podle intervalu cosi zadam
2/ Aby mi to filtrovalo urcite meny

kdyz si pridam napriklad

WHERE r.currency IN ( 'JPY', 'EUR', 'GBP') tak mi to stejne vybere jen JPY
Kajman_
Profil *
1 SELECT @nextdate := from_unixtime( floor( unix_timestamp( date ) /7200 ) *7200) zaokrouhleno_dolu, @nextdate := @nextdate + 7200 dalsi_hranice, r.*

2 lze řešit např. třemi dotazy, případně doplnit další proměnnou a kontrolovat i tu

Taky se trošku snaž :-)
Kcko
Profil
Ja se snazim ale tohle uz moc nechapu a nejsem vubec v klidu.

2/ si vyresim sam
1/ haze tyto vysledky coz neni uplne cajk


zaokrouhleno_dolu dalsi_hranice id currency_code date mid_rate
2008-03-20 15:00:00 9208 3 EUR 2008-03-20 15:29:12 25.348
2008-03-20 15:00:00 9208 18 EUR 2008-03-20 15:34:13 28.141
2008-03-20 15:00:00 9208 33 EUR 2008-03-20 15:39:13 26.246
2008-03-20 15:00:00 9208 48 EUR 2008-03-20 15:44:14 25.26
2008-03-20 15:00:00 9208 63 EUR 2008-03-20 15:49:14 27.926
2008-03-20 15:00:00 9208 78 EUR 2008-03-20 15:54:14 27.62



Uz nevybira to co ma ale skoro vsecko
Kcko
Profil

 SET @nextdate = '0000-00-00';# MySQL vrátil prázdný výsledek (tj. nulový počet řádků).
# MySQL vrátil prázdný výsledek (tj. nulový počet řádků).
# MySQL vrátil prázdný výsledek (tj. nulový počet řádků).
SELECT @nextdate := from_unixtime( floor( unix_timestamp( date ) /14400 ) *14400 +14400 ) tmp, r. *
FROM cis_rates r
WHERE r.date
BETWEEN '2008-3-15'
AND '2008-3-25'
AND currency_code
IN (
'EUR'
)
HAVING r.date >= @nextdate
ORDER BY r.date 





Tvuj puvodni dotaz ( po 4 hodinach )
2008-03-20 17:00:00  	3  	EUR  	2008-03-20 15:29:12  	25.348
2008-03-20 21:00:00 	288 	EUR 	2008-03-20 17:04:20 	28.986
2008-03-21 01:00:00 	1008 	EUR 	2008-03-20 21:04:32 	26.109
2008-03-21 05:00:00 	1728 	EUR 	2008-03-21 01:04:42 	26.692


Vypada to dobre az na to druhe datum? Jak je to mozne? :/
Kajman_
Profil *
A co je na tom špatně? Ten kurz 28.986? A v db je na řádku s id 288 jaký kurz?
Kcko
Profil
NO uz ani nevim, myslel sem ze to ma jit po 4h takze kdyz ten prvni je v tech 15:29 tak dalsi by mel byt +4h starsi
Kajman_
Profil *
První by měl být hnedka po půlnoci, ale prostě první po půlnoci je asi v 15:29.
Kcko
Profil
To jo ale me jde o ten druhy cas , 17:04 , kdyz je prvni 15:29 tak dalsi nemuze byt 17:xx kdyz je to o 4 hodiny ne?
Kajman_
Profil *
Může. Protože se ten čas zaokrouhlí dolů na 13:00. Máš to takhle v tom prvním postu.
Kcko
Profil
Tak to jsme si asi nerozumeli :|

Zaokrouhlovat se ma pouze po pul hodinach ... vzdy ( cili 13:37 -> 13:30, 13:53 -> 13:30, 9:29 -> 9:00 )
a z techto zaokrouhlenych casu potrebuji vybrat intervaly ( 30 min, 60 min, 2h, 4h, 1 den)


Priklad

9:02 -> 9:00
9:37 -> 9:30
10:12 -> 10:00
13:11 -> 13:00
13:53 -> 13:30

Kdyz si nekdo zada 30 min interval vybere mu to casy 9:00, 9:30, 10:00, 13:00, 13:30
Kdyz si nekdo zada 1h interval, vyberemu to 9:00, 10:00, 13:00

Kdyz nekdo zada po 2h tak by mu to melo vybrat 9:00 ( 11h neni), a 13h

po 4h 9 a 13

a po 1 dni .. 9:00 protoze to je prvni datum ve dni



Pujde to ?
Kcko
Profil
Tak uz sem si pomohl ;)

select
id,
currency_code,
date,
mid_rate ,
FLOOR(unix_timestamp(date)/1800) as inter
from cis_rates
WHERE currency_code = 'EUR'
group by currency_code, inter

10 tisic zaznamu , cas 0,0091 a vybere to presne co chci :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0