We have sensors in our building that output data every minute which we want to use in a dimensional model. Therefore we need a Time Dimension to aggregate data on parts of the day. How do you create and populate a Time Dimension?
International Time Dimension |
Solution
Since creating and populating a Time Dimension is a one-time job, T-SQL is probably the best way to accomplish this. For this example we need a Time Dimension on minute level and therefore we have created a loop that executes a insert query 1440 times (24hours * 60minutes).
Besides the hours and minutes we also want to add a name of the day part in two languages and a couple of time strings in both 12 and 24hour notation to make this dimension usable for various countries.
-- Drop the table if it already exists IF OBJECT_ID('dbo.DimTime', 'U') IS NOT NULL BEGIN DROP TABLE dbo.DimTime; END -- Then create a new table CREATE TABLE [dbo].[DimTime]( [TimeId] [int] IDENTITY(1,1) NOT NULL, [Time] [time](0) NULL, [Hour] [int] NULL, [Minute] [int] NULL, [MilitaryHour] int NOT null, [MilitaryMinute] int NOT null, [AMPM] [varchar](2) NOT NULL, [DayPartEN] [varchar](10) NULL, [DayPartNL] [varchar](10) NULL, [HourFromTo12] [varchar](17) NULL, [HourFromTo24] [varchar](13) NULL, [Notation12] [varchar](10) NULL, [Notation24] [varchar](10) NULL ); -- Needed if the dimension already existed -- with other column, otherwise the validation -- of the insert could fail. GO -- Create a time and a counter variable for the loop DECLARE @Time as time; SET @Time = '0:00'; DECLARE @counter as int; SET @counter = 0; -- Two variables to store the day part for two languages DECLARE @daypartEN as varchar(20); set @daypartEN = ''; DECLARE @daypartNL as varchar(20); SET @daypartNL = ''; -- Loop 1440 times (24hours * 60minutes) WHILE @counter < 1440 BEGIN -- Determine datepart SELECT @daypartEN = CASE WHEN (@Time >= '0:00' and @Time < '6:00') THEN 'Night' WHEN (@Time >= '6:00' and @Time < '12:00') THEN 'Morning' WHEN (@Time >= '12:00' and @Time < '18:00') THEN 'Afternoon' ELSE 'Evening' END , @daypartNL = CASE WHEN (@Time >= '0:00' and @Time < '6:00') THEN 'Nacht' WHEN (@Time >= '6:00' and @Time < '12:00') THEN 'Ochtend' WHEN (@Time >= '12:00' and @Time < '18:00') THEN 'Middag' ELSE 'Avond' END; INSERT INTO DimTime ([Time] , [Hour] , [Minute] , [MilitaryHour] , [MilitaryMinute] , [AMPM] , [DayPartEN] , [DayPartNL] , [HourFromTo12] , [HourFromTo24] , [Notation12] , [Notation24]) VALUES (@Time , DATEPART(Hour, @Time) + 1 , DATEPART(Minute, @Time) + 1 , DATEPART(Hour, @Time) , DATEPART(Minute, @Time) , CASE WHEN (DATEPART(Hour, @Time) < 12) THEN 'AM' ELSE 'PM' END , @daypartEN , @daypartNL , CONVERT(varchar(10), DATEADD(Minute, -DATEPART(Minute,@Time), @Time),100) + ' - ' + CONVERT(varchar(10), DATEADD(Hour, 1, DATEADD(Minute, -DATEPART(Minute,@Time), @Time)),100) , CAST(DATEADD(Minute, -DATEPART(Minute,@Time), @Time) as varchar(5)) + ' - ' + CAST(DATEADD(Hour, 1, DATEADD(Minute, -DATEPART(Minute,@Time), @Time)) as varchar(5)) , CONVERT(varchar(10), @Time,100) , CAST(@Time as varchar(5)) ); -- Raise time with one minute SET @Time = DATEADD(minute, 1, @Time); -- Raise counter by one set @counter = @counter + 1; END
Below a very basic example of the usage of this Time Dimension. The LightsAttrium is 0 or 1 indicating whether the lights in the atrium are on or off. By using the average of that during a daypart (night, moning, etc) it shows the percentage of the lights being on. At night it's almost always on and during the afternoon it's off most of the time.
Basic example of usage. |
Conclusion
Above a very complete, but yet still basic, example of a Time Dimension. You can add or remove columns for your own specific purposes (let us know the additions in the comments below). Extending this to for example seconds is very easy. Just change the 1440 in the WHILE to 86400 (24*60*60) and change the DATEADD at the bottom to "second" instead of "minute".
No comments:
Post a Comment
All comments will be verified first to avoid URL spammers. यूआरएल स्पैमर से बचने के लिए सभी टिप्पणियों को पहले सत्यापित किया जाएगा।