Pogledajte određenu poruku
Staro 29. 03. 2012.   #4
dee
Domagoj Horvat
Expert
 
Avatar dee
 
Datum učlanjenja: 24.07.2006
Lokacija: Zagreb
Poruke: 502
Hvala: 22
10 "Hvala" u 8 poruka
dee is on a distinguished road
Pošaljite ICQ poruku za dee
Default

Citat:
Originalno napisao jablan Pogledajte poruku
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
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!
__________________
postoje ludosti bez kojih je nemoguce ljudsko dostojanstvo
dee je offline   Odgovorite uz citat