I just needed a temporary solution to hold my iPad at my desk. It’s worked out pretty well. Thought I’d post the tip:
It’s an Office Depot Plate Holder, Clear Item # 544474
I just needed a temporary solution to hold my iPad at my desk. It’s worked out pretty well. Thought I’d post the tip:
It’s an Office Depot Plate Holder, Clear Item # 544474
In that spirit, yesterday I blew away v1 of my website and started up this version. This will remain a work in progress for a while, since other client commitments will have me quite busy through June.
Anyone using WordPress who has themes or plugins that they love, please leave a comment.
I am seeing more call for Time Dimensions. By that I mean Time-of-Day Dimensions. So now I have to retrain myself to call Date Dimensions “Date” and Time Dimensions “Time”.
As a follow up to this post, here’s some DDL and a quick routine to generate a time of day table. The resolution is to the second, which so far has proved sufficient for my clients’ purposes.
Enjoy
SET nocount ON
/*
CREATE TABLE [dbo].[dim_Time](
[TimeId] [int] NOT NULL,
[Time] [time](7) NULL,
[Hours] [tinyint] NULL,
[Minutes] [tinyint] NULL,
[Seconds] [tinyint] NULL,
CONSTRAINT [PK_dim_Time] PRIMARY KEY CLUSTERED
(
[TimeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
TRUNCATE TABLE [dbo].[dim_Time]
GO
SELECT * FROM dbo.dim_time
*/
DECLARE @second1 INT = 0
DECLARE @currtime TIME
DECLARE @msg VARCHAR(30) = ”
WHILE @second1 < 86400
BEGIN
SELECT @second1 = @second1 + 1
SELECT @currtime = Dateadd(ss, @second1, ’00:00.00′)
– SELECT
–DatePart(hh, @currtime) * 10000 +
–DatePart(mi, @currtime) * 100 +
–DatePart(ss, @currtime) AS TimeID
–, @currtime AS [Time]
–, DatePart(hh, @currtime) AS [Hours]
–, DatePart(mi, @currtime) AS [Minutes]
–, DatePart(ss, @currtime) AS [Seconds]
INSERT dbo.dim_time
([TimeID],
[Time],
[Hours],
[Minutes],
[Seconds])
VALUES (
Datepart(hh, @currtime) * 10000 +
Datepart(mi, @currtime) * 100 +
Datepart(ss, @currtime),
@currtime,
Datepart(hh, @currtime),
Datepart(mi, @currtime),
Datepart(ss, @currtime) )
IF @second1 % 1000 = 0
BEGIN
SELECT @msg = ‘Now Processing ’ + CAST(@second1 AS VARCHAR(12))
PRINT @msg
END
END
Whenever I do something really stupid, rather than keep it to myself, I prefer to blog about it for the entire world to see. Even better – I came up with a debugging technique to save myself from my own, er, stupidity.
The scenario is this: I am developing some SQL Server Analysis Services Date Calculations in MDX for a client. They have three different Date Hierarchies, and wanted the standard, Previous Period, Period to Date, etc calculations. (For a very good explanation of the techniques involved, read this PDF first, then study this refinement from Mosha Pasumansky. )
The MDX looks like this:
Scope([Calculation].[Calculation].[Previous Period]);
([Calendar].[Calendar].[Date]) = ([Calculation].[Current Period], ParallelPeriod([Calendar].[Calendar].[Calendar Year],1));
([Calendar].[Week].[Calendar Week].MEMBERS) = ([Calculation].[Current Period], [Calendar].[Week].Lag(52));
([Calendar].[Calendar].[Calendar Month].MEMBERS) = ([Calculation].[Current Period], [Calendar].[Calendar Month].Lag(12));
([Calendar].[Calendar].[Calendar Quarter].MEMBERS) = ([Calculation].[Current Period], [Calendar].[Calendar Quarter].Lag(4));
([Calendar].[Calendar].[Calendar Year].MEMBERS) = ([Calculation].[Current Period], [Calendar].[Calendar Year].Lag(1));
([Calendar].[NRF].[NRF Week].MEMBERS) = ([Calculation].[Current Period], ParallelPeriod([Calendar].[NRF].[NRF Week],1));
([Calendar].[NRF].[NRF Period].MEMBERS) = ([Calculation].[Current Period], [Calendar].[NRF Period].Lag(13));
([Calendar].[NRF].[NRF Quarter].MEMBERS) = ([Calculation].[Current Period], [Calendar].[NRF Quarter].Lag(5));
([Calendar].[NRF].[NRF Year].MEMBERS) = ([Calculation].[Current Period], ParallelPeriod([Calendar].[NRF].[NRF Year],1));
End Scope;
Devil: You don’t need to set up a separate star schema database
Angel: Yes you do. We don’t want to interfere with the operational systems
Devil: It’s sooo much work
Angel: We want to create a simplified schema to benefit our end users
Devil: Phooeh. ETL is BORING
Devil: Just query the source system directly
Devil: What could be better than fresh data
Devil: C’mon the reports not that big
Devil: Everybody’s doing it
Intrepid BI Architect: sigh…
Anyone who has worked with me or taken training from me has seen some variant of this diagram. It’s not an original concept, although this version has been refined to include my personal experience with many Business Intelligence implementations, as well as my bias towards both the Kimball Business Dimensional methodology and using Microsoft SQL Server (especially Analysis Services) as part of successful deployments.
This diagram is conceptual, although I have designed systems that did have physical servers for each of the servers represented, and these worked very, very well.
I have lots to say about this, and will continue to do so on this blog. Perhaps the most significant concept to mention at the outset is that this is a recipe for success with Business Intelligence. Put another way, the level of success I’ve had with BI environments corresponds pretty closely with how well the architecture of these environments matched this diagram. (Also note that I said “a” recipe for success – not “the” recipe for success. I acknowledge that there are other approaches, but this is the one I’ve used successfully for over a decade.)
Two important concepts inherent in this diagram are:
a) each layer in this diagram has a primary purpose. From an architecture standpoint, designing these functional layers to do only a single thing very well creates a robust, yet simple, environment.
b) There are well-defined interfaces between each functional layer. Having clearly defined boundaries allows the processes to be moved from server to server (which enables important operational benefits like high-availability, disaster recovery, and performance tuning)
What are these primary purposes mentioned above, and how do they benefit the overall architecture?
BTW – I call this the “Million Dollar” BI Architecture Diagram because:
(Minor Avatar spoilers below – in case you’re one of the 3 people who hasn’t seen it yet)
I was driving to a clients this past week and just free-associating, listening to an NPR segment about the movie Avatar and also thinking about this upcoming Business Intelligence implementation.
In the movie, “Avatar”, the “Tree of Souls” is a nexus where sentient beings can connect and understand the will of that planet’s deity. At some point the “AllMother”, through the “Tree of Souls”, acts on the different populations to coordinate their efforts and accomplish something truly remarkable.
It occurred to me that that is what we are trying to do with Business Intelligence: allow people to connect to information and by virtue of the information revealed, align and influence their actions to accomplish something truly remarkable.
So you see, the movie Avatar is really about Business Intelligence.
Is Business Intelligence your company’s “Tree of Souls” ?