|
SQL baze podataka - Sponzor: Baze-Podataka.net MySQL, MSSQL, Oracle, Access, ODBC. Ako imate problem brže i preciznije ćete dobiti odgovor ako priložite strukturu tabela ili skript koji kreira tabele i puni ih test podacima umesto što to problem opisujete samo rečima. Sponzor: Baze-Podataka.net - Blog o bazama podataka |
|
Alati teme | Način prikaza |
28. 03. 2012. | #1 |
Domagoj Horvat
Expert
|
I'm too old for this **** [last 24 hrs distribution query]
ne znam jesam li umoran il sta je, al nikako ne mogu nabost neko elegantno rjesenje...pa ako nekome pada stogod napamet, bit cu vrlo zahvalan...
u bazu biljezim podatak X(int) svaku minutu i to na nacin da upisujem samo ako se razlikuje od prethodne minute. dakle, moze biti zapisa svaku minutu, a moze ih ne biti satima. treba mi query koji vraca MAX(X) za posljednja 24 sata (po satima). za 24 sata u nekom danu jos i mogu izvuci (dakle, kad krece sa 0 i zavrsava s 23) medjutim dio kad krece sa npr 16 (jer u 16 sati covjek pokrene report) i zavrsi sa 15) - nikako nabost nesto lijepo. meni treba TSQL ali to nije toliko vazno...i opisna ideja je i vise nego dosta. Hvala!
__________________
postoje ludosti bez kojih je nemoguce ljudsko dostojanstvo |
28. 03. 2012. | #2 |
VD IT Direktora
Invented the damn thing
Datum učlanjenja: 08.06.2005
Lokacija: Beograd
Poruke: 2.118
Hvala: 503
1.307 "Hvala" u 282 poruka
|
http://sqlfiddle.com/#!1/a32c6/3
Edit: sad videh da ti je problem da počneš od npr. 15-og sata. Možeš to rešiti tako što ćeš u tabelu hours dodati još 24 sata, početi od npr. 15-og i koristiti "LIMIT 24". Evo: http://sqlfiddle.com/#!1/479c1/3
__________________
blog Poslednja izmena od jablan : 28. 03. 2012. u 21:27. |
"Hvala" jablan za poruku: |
29. 03. 2012. | #3 |
Branimir Momcilovic
Qualified
Datum učlanjenja: 15.02.2006
Lokacija: Beograd
Poruke: 167
Hvala: 47
25 "Hvala" u 8 poruka
|
Trebalo bi da može i ovako (TSQL):
Kôd:
SELECT DATEPART(HH, TimeColumn) AS Hour, MAX(X) as MaxX FROM [Table] WHERE TimeColumn > DATEADD(DD, -1, GETDATE()) GROUP BY DATEPART(HH, TimeColumn) Kôd:
SELECT MAX(DATEPART(DD, TimeColumn)) AS Day, DATEPART(HH, TimeColumn) AS Hour, MAX(X) as MaxX FROM [Table] WHERE TimeColumn > DATEADD(DD, -1, GETDATE()) GROUP BY DATEPART(HH, TimeColumn) ORDER BY Day, Hour
__________________
Važnije je biti ljubazan, nego biti u pravu. |
29. 03. 2012. | #4 | |
Domagoj Horvat
Expert
|
Citat:
Ima jos nesto sto nisam naveo u inicijalnom postu, a to je da nakon sto se dobije redoslijed, sve null (prazne) recorde iz desne tabele (nakon left outer joina) treba popuniti sa zadnjom vrijednosti iz iste tabele koja nije null. dakle, ako je na 14-om satu naisao na null, onda mora ici do prvog ranijeg sata koji nije null i sve izmedju napuniti tom vrijednoscu. (to je posljedica cinjenice da u bazu biljezim samo promjene, a ne sve) Moj pristup je bio malo drugaciji. - tmp tabela sa kolonama Sat, Vrijednost i identity autoincrement kolonom - u nju prvo upisem sat/vrijednost za sve zapise u posljednjih 24 sata kojima je HOUR(timestamp) veci od HOUR(Current_Date) (to su jucerasnji) - nakon toga upisem sve kojima je hour manji od trenutnog (danasnji) - nadjem pocetnu vrijednost rangea posljednjih 24 sata (ako je prvi null ide u proslost dok ne nadje prvi koji nije null) - na kraju CURSOR da popuni praznine Ovaj dio s CURSOROM mi nije drag, rado bih to rijesio deklarativno, ali nakon 2 sata razmisljanja i probavanja nisam uspio i rijesio sam ipak s CURSOROM. Vidjet cemo kako ce se ponasat (setovi nisu nikad preveliki tako da ne bi trebalo igrat neku ulogu u performansama) Ako ce nekome trebat, moje TSQL rjesenje je: [@UserSubscriptionId je ulazni parametar u proceduru] Kôd:
declare @currentHour int set @currentHour = DATEPART(HOUR, getdate()) CREATE TABLE #HoursDistribution ( Id int IDENTITY(1, 1), Hr int, Value int ) INSERT INTO #HoursDistribution ( Hr, Value ) SELECT hrs.Hour, Entries.mNum FROM [Hours] hrs LEFT OUTER JOIN ( SELECT DATEPART(HOUR, [Date]) AS Hr, MAX(NewMessagesNumber) AS mNum FROM NewMessagesHistory WHERE Date >= DateAdd(hh, -24, GETDATE()) AND UserSubscriptionId = @UserSubscriptionId GROUP BY DATEPART(HOUR, [Date]) ) Entries ON hrs.Hour = Entries.Hr WHERE hrs.Hour > @currentHour INSERT INTO #HoursDistribution ( Hr, Value ) SELECT hrs.Hour, Entries.mNum FROM [Hours] hrs LEFT OUTER JOIN ( SELECT DATEPART(HOUR, [Date]) AS Hr, MAX(NewMessagesNumber) AS mNum FROM NewMessagesHistory WHERE Date >= DateAdd(hh, -24, GETDATE()) AND UserSubscriptionId = @UserSubscriptionId GROUP BY DATEPART(HOUR, [Date]) ) Entries ON hrs.Hour = Entries.Hr WHERE hrs.Hour <= @currentHour DECLARE @LastV int SELECT TOP 1 @LastV = MAX(NewMessagesNumber) FROM NewMessagesHistory WHERE Date < DateAdd(hh, -24, GETDATE()) AND UserSubscriptionId = @UserSubscriptionId GROUP BY Id,DATEPART(HOUR, [Date]) ORDER BY Id DESC IF @LastV IS NULL BEGIN update #HoursDistribution set Value = 0 where Id = 1 END ELSE BEGIN update #HoursDistribution set Value = @LastV where Id = 1 END DECLARE @LastValue int DECLARE Stavke_Cursor CURSOR FOR SELECT Id, Hr, Value FROM #HoursDistribution OPEN Stavke_Cursor DECLARE @Idt int DECLARE @Hrt int DECLARE @Valuet int FETCH NEXT FROM Stavke_Cursor INTO @Idt, @Hrt, @Valuet WHILE @@FETCH_STATUS = 0 BEGIN IF @Valuet IS NOT NULL BEGIN SET @LastValue = @Valuet END IF @Valuet IS NULL BEGIN UPDATE #HoursDistribution SET Value = @LastValue WHERE Id = @Idt END FETCH NEXT FROM Stavke_Cursor INTO @Idt, @Hrt, @Valuet END CLOSE Stavke_Cursor DEALLOCATE Stavke_Cursor SELECT * FROM #HoursDistribution DROP TABLE #HoursDistribution Svakako, puno hvala!
__________________
postoje ludosti bez kojih je nemoguce ljudsko dostojanstvo |
|
29. 03. 2012. | #5 | |
Domagoj Horvat
Expert
|
Citat:
__________________
postoje ludosti bez kojih je nemoguce ljudsko dostojanstvo |
|
29. 03. 2012. | #6 |
Branimir Momcilovic
Qualified
Datum učlanjenja: 15.02.2006
Lokacija: Beograd
Poruke: 167
Hvala: 47
25 "Hvala" u 8 poruka
|
Jasno, neće vratiti vrednosti za sate koje nisi imao kao unose, to svakako moraš da "popuniš" nekako
Pričali smo na sličnu temu http://www.devprotalk.com/showthread.php?t=10632
__________________
Važnije je biti ljubazan, nego biti u pravu. Poslednja izmena od BraMom : 29. 03. 2012. u 15:14. Razlog: link |
29. 03. 2012. | #7 | ||
Domagoj Horvat
Expert
|
Citat:
U svakom slucaju, u bazu se biljezi vrijednost samo ako je doslo do promjene. To moze znaciti kontinuirani upisi svake minute proslih x sati medjutim isto tako moze znaciti da nema upisa 10 dana. Koji god slucaj bio - 'last24hours' report trazi upravo to: stanja po satima u zadnjih 24 sata. Tako da, svakako mi ti upisi trebaju, bilo ih fizicki u tabeli ili bili 'zakljuceni' na osnovi proslih vrijednosti. (ovo pisem cisto ako ce netko kasnije citat, da ima kontekst koji mu moze bit eventualno koristan ako treba sto slicno) Citat:
Hvala za link!
__________________
postoje ludosti bez kojih je nemoguce ljudsko dostojanstvo |
||
29. 03. 2012. | #8 | |
VD IT Direktora
Invented the damn thing
Datum učlanjenja: 08.06.2005
Lokacija: Beograd
Poruke: 2.118
Hvala: 503
1.307 "Hvala" u 282 poruka
|
Citat:
http://jablan.radioni.ca/post/101288...sing-self-join
__________________
blog |
|
"Hvala" jablan za poruku: |
29. 03. 2012. | #9 | |
Domagoj Horvat
Expert
|
Citat:
Kôd:
select t1.date, t1.temp, t2.date, t3.date from temperatures t1 left join temperatures t2 on t1.date > t2.date left join temperatures t3 on t3 < t1 and t2 < t3 where t3.date is null order by t1.date, t2.date, t3.date; Mislim da je ovo rjesenje, svakako cu ga probat. Tnx!
__________________
postoje ludosti bez kojih je nemoguce ljudsko dostojanstvo |
|
|
|