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!
|
jablan |
28. 03. 2012. 20:18 |
|
BraMom |
29. 03. 2012. 10:36 |
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)
Ako je bitan i redosled, kad kreće od 16 sati, da ide redom 16,17... pa sledeći dan, onda može ovako:
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
|
Citat:
Originalno napisao jablan
(Napišite 106040)
|
Ovo mi nije palo na pamet sa duplom tabelom sati pa da se uzima odredjeni range. Dobra fora!
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!
|
Citat:
Originalno napisao BraMom
(Napišite 106060)
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)
Ako je bitan i redosled, kad kreće od 16 sati, da ide redom 16,17... pa sledeći dan, onda može ovako:
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
|
Hmm...cini mi se da ovo nece radit ako u tabeli nema zapisa za danasnji dan (sto je sasvim realan slucaj ako u proslih 24 sata nije bilo promjene vrijednosti). Zato je, kako je i kolega jablan napisao, nuzna dodatna tabela u kojoj se drze sati (samo int upisi 0-23 [ili 1-24]) i s kojom se tabela zapisa left outer joina.
|
BraMom |
29. 03. 2012. 14:12 |
|
Citat:
Originalno napisao BraMom
(Napišite 106069)
Jasno, neće vratiti vrednosti za sate koje nisi imao kao unose, to svakako moraš da "popuniš" nekako
|
Mozda nisam bio dovoljno precizan kad sam postavljao uvodno pitanje. Ne bi bilo cudo, umor je vec odradio svoje.
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:
Originalno napisao BraMom
(Napišite 106069)
|
Da, slicna stvar. Nisam naisao na taj topic dok sam trazio.
Hvala za link!
|
jablan |
29. 03. 2012. 20:24 |
Citat:
Originalno napisao dee
(Napišite 106064)
sve null (prazne) recorde iz desne tabele (nakon left outer joina) treba popuniti sa zadnjom vrijednosti iz iste tabele koja nije null.
|
Pogledaj ovde, mislim da lepo može da se primeni na tvoj problem:
http://jablan.radioni.ca/post/101288...sing-self-join
|
Citat:
Originalno napisao jablan
(Napišite 106083)
|
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;
krenuo sam u smjeru self-joina ali ga nisam uspio nabost i na kraju 'prelomio' kursorom. iako, ne treba naravno spominjat, koliko je ruzno proceduralno pisat stvari u SQLu.
Mislim da je ovo rjesenje, svakako cu ga probat.
Tnx!
|
Vreme je GMT +2. Trenutno vreme je 08:53. |
|
Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.
Mišljenja, saveti, izjave, ponude ili druge informacije ili sadržaji nastali na Sajtu su vlasništvo onoga ko ih je kreirao, a ne DevProTalk.com, tako da ne morate da se oslanjate na njih.
Autori poruka su jedini odgovorni za ovakve sadržaje. DevProTalk.com ne garantuje tačnost, kompletnost ili upotrebnu vrednost informacija, stavova, saveta ili datih izjava. Ne postoje uslovi pod kojima bi mi bili odgovorni za štetu ili gubitak koji je posledica bilo čijeg oslanjanja na nepouzdane informacije, ili bilo kakve informacije nastale kroz komunikaciju između registrovanih članova.Web sajt može sadržavati linkove na druge web sajtove na Internetu ili neke druge sadržaje. Ne kontrolišemo niti podržavamo te druge web sajtove, niti smo pregledali bilo kakve sadržaje na takvim sajtovima. Mi nećemo biti odgovorni za legalnost, tačnost ili prikladnost bilo kog sadržaja, oglasa, proizvoda, usluga ili informacije lociranim na ili distribuiranih kroz druge web sajtove, niti za bilo kakvu štetu nastalu kao posledica takvih informacija. DevProTalk.com drži i čuva druga prava vlasništva na web sajtu. Web sajt sadrže materijale zaštićene copyright-om, zaštitne znakove i druge informacije o pravu vlasništva ili softver. Članovi mogu poslatu informacije zaštićene pravima vlasništva njihovih nosilaca i ona ostaju zaštićena bez obzira da li su oni koji prenose te informacije to naveli ili ne. Osim informacija koje su u javnom vlasništvu ili za koje dobijete dozvolu, nemate pravo da kopirate, modifikujete ili na bilo koji način menjate, objavljujete, prenosite, distribuirate, izvršavate, prikazujete ili prodajte bilo koju informaciju zaštićenu pravima vlasništva. Slanjem informacija ili sadržaja na bilo koji deo DevProTalk.com, Vi automatski dozvoljavate i predstavljate garanciju da imate pravo da dozvolite DevProTalk.com ili članovima DevProTalk.com bespovratnu, kontinualnu, neograničenu, globalnu dozvolu da koriste, kopiraju, izvršavaju, prikazuju i distribuiraju takve informacije i sadržaje i da iz takvih sadžaja koriste bilo koji deo u bilo koje svrhe, kao i pravo i dozvolu da koriste gore navedene sadržaje. Svi zaštitni znakovi (trademarks), logotipi, oznake usluga, firme ili imena proizvoda koji se pominju na ovom web sajtu su vlasništvo kojim raspolažu njihovi vlasnici.