Citat:
Originalno napisao jablan
|
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!