Jag har en tabell med reservationer som ser ut ungefär så här : Jag tycker du krånglar till det, Tack för svaret, Det där borde funka rätt bra tycker jag, Joina datumposter med en kalender
<info>
<b>Reservations</b>
--------------
[Date] (DateTime)
[ResourceEntity_ID] (int)
[Time] (int)
</info>
Detta motsvarar alltså en bokning av en viss maskin (ResourceEntity) ett visst datum ett visst antal minuter. Nu vill jag skapa en beläggningsrapport med en post per datum (inom ett intervall givetvis) och resursenhet, dvs även datum där det inte finns några bokningar skall ha en post med tiden 0.
Alltså, låt säga att jag har två resurser 1 & 2, och att följande bokningar finns :
<b>Tabellen Reservations</b>
Date ResourceEntity_ID Time
---------------------------------------------
2005-01-01 1 10
2005-01-02 1 20
2005-01-02 2 30
2005-01-02 2 40
2005-01-03 2 50
Vill jag ha en beläggningsrapport för tiden 2005-01-01 till 2005-01-03 så vill jag alltså få ut följande data :
<b>Önskat resultat</b>
Date ResourceEntity_ID ReservedTime
---------------------------------------------
2005-01-01 1 10
2005-01-02 1 20
2005-01-03 1 0
2005-01-01 2 0
2005-01-02 2 70
2005-01-03 2 50
Min tanke var att skapa en temporär tabell med alla datum i intervallet och sedan joina ihop detta på något sätt med tabellen Reservations, men det sista steget lyckas jag inte med. Den temporära tabell med datumposter har jag lyckats skapa med hjälp av följande artikel :
http://www.databasejournal.com/features/mssql/article.php/3502256
Här är SQL:en för att skapa kalenderposterna om det nu hjälper:
CREATE PROCEDURE ManufacturingPlanning_GetManufacturingReservationReport
@StartDate DateTime=NULL,
@Days int=365
AS
create table #Calendar
(
Dateid int identity(1,1) constraint Calendar_PK primary key CLUSTERED,
[Date] datetime,
)
declare @n int
set @n =1
set @StartDate = @StartDate -1
while @n <= @Days
begin
insert into #Calendar(date) select @StartDate+@n
set @n=@n+1
end
select * from #Calendar -- Visa resultatet
drop table #Calendar
GO
Är detta rätt väg att gå? Går det ens att lösa? Alla tips mottages tacksamt...
Sv: Joina datumposter med en kalender
varför inte se det som en rapport som du skapar när du skriver ut din output?
alltså typ:
(PSEUDOKOD - funkar inte..)
<code>
DR = GetDataReader()
dim bHasData As Boolean
bHasData = DR.Read()
dat = StartDate
Do Until dat = EndDate
'alternativt loopa genom en array med godkända datum om du vill skippa helger t.ex.
If bHasData AndAlso dat = DR("datum")
'skriv ut datum och bokningsinfo
' för flera tillfällen per datum: loopa tills datum ändras eller är slut.
Else
'datumet fanns inte i databasen. skriv ut dat och att det är "ledigt"
End If
dat = AddDays(dat, 1) ' nästa datum
If bHasData Then bHasData = DR.Read() ' nästa rad
Loop
</code>
Det är mer rakt på sak och ger bättre prestanda än att skapa en temp-tabell och joina mot den..Sv:Joina datumposter med en kalender
Grejen är dock (och det kanske jag borde ha sagt) att datan skall bindas till ActiveReports, och det var därför jag ville ha datan på detta viset. Kanske blir jag dock så illa tvungen att skapa rapporten unbound och skriva lite kod för att generera de icke-existerande raderna i stället.
Jag har dock i princip lyckats fixa SQL:en nu. Cross join var lösningen :
select #Calendar.[Date] , RE.ResourceEntity_ID ,
(select sum(Time) from Reservation where ResourceEntity_ID=RE.ResourceEntity_ID and [Date]=#Calendar.[Date]) as Time
from #Calendar
cross join ResourceEntity RE
where RE.ResourceEntity_ID in
(select distinct ResourceEntity_ID
from Reservation
where Reservation.Date>=@StartDate and Reservation.Date<=@StartDate+@Days)
Som du säger är ovanstående nog varken snyggt eller prestandamässigt bra.
Sv: Joina datumposter med en kalender
se bara till att Reservation.Date är en indexerad kolumn i databasen.