zondag 17 juli 2011

SSAS/SSRS : Building a graph for analyzing a subset related to the whole set

Introduction
My client has some wishes about a graph that shows a subset of facts of certain locations against the whole population of locations. They want to highlight the locations and show their position in a sorted diagram. Below you can see the end result of the graph.



Scenario
For this purpose i've quickly created a small cube. First i build a script for building the following tables:
  • DimDate
  • DimLocation
  • DimDepartment
  • BridgeLocationDepartment
 And they are related as follows:



This situation is already explained in more detail in my former posts:
  • Modeling a N:M relation between dimensions (part I).
  • Building a multivalue dimension construction in SSAS ( part II).
  • Joining issue with MDXing of M2M dimension (part III).
  • Cascading parameters and M2M dimensions  (part IV)
I've created the following example script:

USE [GraphProblem]
GO

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FactTest]') AND type in (N'U'))
DROP TABLE [dbo].[FactTest]
GO

CREATE TABLE [dbo].[FactTest](
[FactTestID] [int] IDENTITY(1,1) NOT NULL,
[FK_Date_Key] [int] NOT NULL,
[FK_Location_Key] [int] NOT NULL,
[FactTestCount] [int] NOT NULL
) ON [PRIMARY]
GO

----
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DimLocation]') AND type in (N'U'))
DROP TABLE [dbo].[DimLocation]
GO

CREATE TABLE [dbo].[DimLocation](
[Location_Dim_key] [int] NOT NULL,
[Location_Code] [int] NOT NULL,
[Location_Description] [varchar](50) NOT NULL
) ON [PRIMARY]
GO

----
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DimDepartment]') AND type in (N'U'))
DROP TABLE [dbo].[DimDepartment]
GO

CREATE TABLE [dbo].[DimDepartment](
[Department_Dim_key] [int] NOT NULL,
[Department_Code] [int] NOT NULL,
[Department_Description] [varchar](50) NOT NULL
) ON [PRIMARY]
GO

---
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[BridgeLocationDepartment]') AND type in (N'U'))
DROP TABLE [dbo].[BridgeLocationDepartment]
GO

CREATE TABLE [dbo].[BridgeLocationDepartment](
[BridgeLocationDepartment_ID] [int] IDENTITY(1,1) NOT NULL,
[FK_Location_Key] [int] NOT NULL,
[FK_Department_Key] [int] NOT NULL,
[Valid_From] [date] NOT NULL,
[Valid_Until] [date] NOT NULL
) ON [PRIMARY]
GO

---
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DimDate]') AND type in (N'U'))
DROP TABLE [dbo].[DimDate]
GO

CREATE TABLE [dbo].[DimDate](
[Date_dim_key] [int] NULL,
[Date_Year] [int] NULL
) ON [PRIMARY]
GO

---

INSERT INTO dbo.DimDepartment (Department_Dim_key, Department_Code, Department_Description)
VALUES
(1, 1, 'Department A'),
(2, 2, 'Department B'),
(3, 3, 'Department C'),
(4, 4, 'Department D'),
(5, 5, 'Department E'),
(6, 6, 'Department F'),
(7, 7, 'Department G'),
(8, 8, 'Department H'),
(9, 9, 'Department I'),
(10, 10, 'Department J')

INSERT INTO dbo.DimLocation (Location_Dim_key, Location_Code, Location_Description)
VALUES
(1, 1, 'Location 1'),
(2, 2, 'Location 2'),
(3, 3, 'Location 3'),
(4, 4, 'Location 4'),
(5, 5, 'Location 5'),
(6, 6, 'Location 6'),
(7, 7, 'Location 7'),
(8, 8, 'Location 8'),
(9, 9, 'Location 9'),
(10, 10, 'Location 10')

INSERT INTO dbo.BridgeLocationDepartment (FK_Location_Key, FK_Department_Key, Valid_From, Valid_Until)
VALUES
(1, 1, '2011-01-01', '9999-12-31'),
(2, 1, '2005-01-01', '9999-12-31'),
(2, 2, '2005-01-01', '9999-12-31'),
(3, 3, '2005-01-01', '9999-12-31'),
(4, 3, '2005-01-01', '9999-12-31'),
(4, 4, '2005-01-01', '9999-12-31'),
(5, 5, '2005-01-01', '9999-12-31'),
(5, 7, '2005-01-01', '9999-12-31'),
(6, 6, '2005-01-01', '9999-12-31'),
(6, 7, '2005-01-01', '9999-12-31'),
(7, 7, '2005-01-01', '9999-12-31'),
(8, 8, '2005-01-01', '9999-12-31'),
(9, 9, '2005-01-01', '9999-12-31'),
(9, 10, '2005-01-01', '9999-12-31'),
(10, 10, '2005-01-01', '9999-12-31' )

INSERT INTO dbo.DimDate
VALUES (1,2000),
(2, 2001),
(3, 2002),
(4, 2003),
(5, 2004),
(6, 2005),
(7, 2006),
(8, 2007),
(9, 2008),
(10, 2009),
(11, 2010),
(12, 2011),
(13, 2012),
(14, 2013),
(15, 2014),
(16, 2015)


INSERT INTO [dbo].[FactTest]([FK_Date_Key],[FK_Location_Key],[FactTestCount])
VALUES
(7, 1, 1),(7, 2, 1),(8, 3, 1),(9, 3, 1),(9, 2, 1),(10, 4, 1),(10, 5, 1),(10, 5, 1),(11, 5, 1),(7, 7, 1),
(9, 4, 1),(10, 3, 1),(11, 10, 1),(12, 6, 1),(10, 2, 1),(9, 9, 1),(8, 7, 1),(5, 7, 1),(6, 1, 1),(7, 5, 1),
(8, 1, 1),(7, 1, 1),(7, 2, 1),(8, 3, 1),(9, 2, 1),(10, 4, 1),(10, 5, 1),(10, 5, 1),(7, 7, 1),(9, 4, 1),
(10, 3, 1),(11, 10, 1),(10, 2, 1),(9, 9, 1),(8, 7, 1),(5, 7, 1),(6, 1, 1),(7, 5, 1),(8, 1, 1),(10, 5, 1),
(7, 7, 1),(9, 4, 1),(10, 3, 1),(11, 10, 1),(10, 2, 1),(9, 9, 1),(8, 7, 1),(5, 7, 1),(6, 1, 1),(7, 5, 1),
(8, 1, 1),(10, 5, 1),(10, 5, 1),(11, 5, 1),(7, 7, 1),(9, 4, 1),(10, 3, 1),(11, 10, 1),(12, 6, 1),(10, 2, 1),
(9, 9, 1),(5, 7, 1),(6, 1, 1),(7, 5, 1),(8, 1, 1),(10, 5, 1),(10, 5, 1),(11, 5, 1),(8, 1, 1),(7, 1, 1),
(7, 2, 1),(8, 3, 1),(9, 2, 1),(10, 4, 1),(10, 5, 1),(10, 5, 1),(10, 1, 1),(10, 2, 1),(10, 3, 1),(10, 7, 1),
(10, 5, 1),(10, 9, 1),(10, 2, 1),(10, 1, 1),(10, 4, 1),(10, 4, 1),(10, 5, 1),(10, 9, 1),(10, 2, 1)


Created a cube on the datastructure with following structure:


The dimension usage tab:


And now take a look at the dimension browser tab:


So the values for 2009 seems an interesting candidate for simulating the situation. There are certain departments and locations which can be used for testing my graphproblem. I would like to focus on Department C (location 3 and 4) and department G (Location 5 and 7).

The solution
Now, let's build the report with a graph and a parameter "department". So when the department is selected i want to show the locations in highlighted manner. You can see this in the diagram in the introduction section. Initially, it would look something like this (the customer don't want the names of the locations shown):

But the locations of department C is not red (the two 5's). It's not possible to do a lookup between two datasets in SQL Server 2008 (SQL Server 2008 R2 does have a lookup function). Therefore i decided to alter my MDX query and add an extra column indicating whether a location belongs to a selected department at the parameter. So i changed the standard MDX query to this:

WITH MEMBER [Measures].[test]
AS
IIF(ISEMPTY((EXISTS([DimLocation].[LocationDescription].CURRENTMEMBER, {STRTOSET(@DimDepartmentDepartmentDescription, CONSTRAINED)}, "FactTest").item(0), [Measures].[FactTestCount])), 0, 1)

SELECT {[Measures].[FactTestCount], [Measures].[test]} ON COLUMNS,
[DimLocation].[LocationDescription].[LocationDescription] ON ROWS
FROM (SELECT ( { [DimDate].[DateYear].&[2009] }) ON COLUMNS
               FROM [GraphProblem])


Resulting in (when testing with department C):

The most important section is the WITH section where IIF and EXISTS do some nifty work. The EXISTS function checks whether the set of locations are related to the set of departments (selected  with the parameter). The EXISTS returns a NULL when there is not a relation and a measure value  when there is a relation. So with the IIF and the ISEMPTY it's possible to return a 1 (for a relation) and 0 (for no relation)

So now take a look in the report and select the series properties in the diagram and select the Fill tab:


The next thing is checking whether the test measure is 0 or 1 with : "=IIF(Fields!test.Value = 1, "Red", "Blue")". This looks great when i run the report. The locations belonging to department C is highlighted:


When i choose department G the following diagram is shown:

Conclusion
Initially, i wanted to solve this problem in the report but when i found out that SQL Server 2008 doesn't have a lookup function i needed to try other things. There are some solutions available on the internet about  building this with subreports or custom coding but the solution above is a better solution (in my opinion).

Greetz,
Hennie

zaterdag 9 juli 2011

SSAS/SSRS/MDX : Cascading parameters and M2M dimensions

Introduction

Well, today a post about cascading parameters in Reporting Services (SSRS) in combination with MDX coding. Cascading parameters is about defining multiple parameters in such a way that a list of values of  a parameter depends on the values of another parameter. For this post i'll build upon my lab environment as described in my earlier posts:
  • Modeling a N:M relation between dimensions (part I).
  • Building a multivalue dimension construction in SSAS ( part II).
  • Joining issue with MDXing of M2M dimension (part III).
As a matter of fact, this post could be seen as a part IV in this list because the problem is also related with the M2M dimension construction. This is explained in my former post (part III).


Scenario
What i'll describe in this post is building a cascading parameter build upon two datasets: one for department and one for location. I've seen enough examples of building parameters on SQL queries but there are not that many examples based on MDX. As decribed in the earlier posts (see above) i've the following situation:
  • Department A
    • Location 1.
    • Location 2.
  • Department B.
    • Location 2.
  • Department C.
    • Location 3.
    • Location 4.
So, the cascading parameter should show location 1 and 2 when the first parameter is department A.  Again,  when department C is chosen the other parameter should be limited to location 3 and 4.

Building the report 
First, let's setup the report in Reporting Services that returns a department, a location and a count field. I've created a datasource in SSRS, built a dataset and added the two parameters: Department and Location.


After I pressed OK and returned back to the report i noticed that there are a couple of extra (hidden) datasets created(DepartmentDepartmentDescription and LocationLocationDescription). Dataset1 is MDX query that should return data for the report.

Let's try the report and check if the cascading parameter location is depending on the department parameter. Look at the diagram below and notice that all four locations are shown, even when i choosed a different departments.


Seems that we've to add some more magic to the report. Let's look at the parameter datasets in more detail. I've copied the MDX query of the department dataset below:

WITH
MEMBER [Measures].[ParameterCaption] AS [Department].[Department Description].CURRENTMEMBER.MEMBER_CAPTION
MEMBER [Measures].[ParameterValue] AS [Department].[Department Description].CURRENTMEMBER.UNIQUENAME
MEMBER [Measures].[ParameterLevel] AS [Department].[Department Description].CURRENTMEMBER.LEVEL.ORDINAL
SELECT {[Measures].[ParameterCaption],
[Measures].[ParameterValue],
[Measures].[ParameterLevel]} ON COLUMNS ,
[Department].[Department Description].ALLMEMBERS ON ROWS FROM [MultiValueDimension]


No need for changes here. Let's take a look at the location dataset.

WITH 
MEMBER [Measures].[ParameterCaption] AS [Location].[Location Description].CURRENTMEMBER.MEMBER_CAPTION 
MEMBER [Measures].[ParameterValue] AS [Location].[Location Description].CURRENTMEMBER.UNIQUENAME 
MEMBER [Measures].[ParameterLevel] AS [Location].[Location Description].CURRENTMEMBER.LEVEL.ORDINAL 
SELECT {[Measures].[ParameterCaption], 
[Measures].[ParameterValue], 
[Measures].[ParameterLevel]} ON COLUMNS , 
[Location].[Location Description].ALLMEMBERS ON ROWS 
FROM ( SELECT ( STRTOSET(@DepartmentDepartmentDescription, CONSTRAINED) ) ON COLUMNS 
       FROM [MultiValueDimension])

The problem (as i described in my former post about the showing the right location related at the right department) is that all locations are shown because the relation between location and department isn't enforced. So i need to change the query and two important changes are needed.

First change the WITH part:

WITH 
MEMBER [Measures].[ParameterCaption] AS [Location].[Location Description].CURRENTMEMBER.MEMBER_CAPTION 
MEMBER [Measures].[ParameterValue] AS [Location].[Location Description].CURRENTMEMBER.UNIQUENAME 
MEMBER [Measures].[ParameterLevel] AS [Location].[Location Description].CURRENTMEMBER.LEVEL.ORDINAL

into:

WITH
MEMBER [Measures].[ParameterCaption] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.MEMBER_CAPTION)
MEMBER [Measures].[ParameterValue] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.UNIQUENAME)
MEMBER [Measures].[ParameterLevel] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.LEVEL.ORDINAL)


This part is enforcing the member to NULL when the relation is not there:

and change:

[Location].[Location Description].ALLMEMBERS ON ROWS 

into:

NONEMPTY([Location].[Location Description].ALLMEMBERS,[Measures].[Bridge Location Department Count])

This part is needed to suppress the NULLs but fon't forget to show all locations( for a specific department), even when there is no fact.This is important to notice because when i don't add this extra constraint location 4 isn't shown at Department C. This location doesn't have a factrecord stored.

And the final solution is shown below:

WITH
MEMBER [Measures].[ParameterCaption] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.MEMBER_CAPTION)
MEMBER [Measures].[ParameterValue] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.UNIQUENAME)
MEMBER [Measures].[ParameterLevel] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.LEVEL.ORDINAL)
SELECT {
[Measures].[ParameterCaption],
[Measures].[ParameterValue],
[Measures].[ParameterLevel]} ON COLUMNS ,
NONEMPTY([Location].[Location Description].ALLMEMBERS,[Measures].[Bridge Location Department Count]) ON ROWS
FROM (SELECT (STRTOSET(@DepartmentDepartmentDescription, CONSTRAINED) ON COLUMNS
              FROM [MultiValueDimension]))


The snippet 'FROM (SELECT (STRTOSET(@DepartmentDepartmentDescription, CONSTRAINED) ON COLUMNS FROM [MultiValueDimension]))' will change the location in a cascading parameter.

Now it's time to test this changed query. Starting up the report in preview mode is shown below (department A is showing the two locations 1 and 2):


Let's try another department (department C shows location 3 and location 4):


Conclusion
Main 'problem' is the usage of the M2M dimension (Location 2 Department) that is actually a n:m relation. To enforce the relation you have to use the second parameter of the NONEMPTY() function.

Greetz,
Hennie

vrijdag 1 juli 2011

SSAS: Joining issue with MDXing of M2M dimension (part III)

Hi,

At this moment i'm developing a M2M (or MM) dimension for locations and departments. If you haven't seen my former posts (part I, part II) about this subject, i would recommend reading these posts. One issue i have with the M2M dimensions is getting the right information in the reports (who doesn't;-)) and it took me a while to understand how to handle this. The problem is how to show the locations which don't have a fact for a specific department.

Okay, this is the situation: there are departments and locations and they are n:m related to each other. Therefore i've developed a bridge table for this purpose. In this bridge table i've added a count field. In contrast with my former post i've added an extra record for simulating the scenario i have. So the records in the different tables looks like this:

Query :

SELECT
Location_Description,
Department_Description,
DT.Date_Year,
TestFactCount
FROM dbo.Location L
LEFT OUTER JOIN dbo.TestFact F ON L.Location_Dim_key = F.FK_Location_Key
LEFT OUTER JOIN dbo.DimDate DT ON F.FK_Date_Key = DT.Date_dim_key
INNER JOIN dbo.Bridge_Location_Department B ON B.FK_Location_Key = L.Location_Dim_key
INNER JOIN dbo.Department D ON D.Department_Dim_key = B.FK_Department_Key



Resulting in:


So when the user selects department C two locations should be shown: location 3 and 4. Location 3 has factvalues and location 4 does not have any fact values.

Option 1
Okay the first attempt for building a MDX query for this is:

SELECT [Measures].[Test Fact Count] ON 0,
[Location].[Location Description].[Location Description].MEMBERS ON 1
FROM ( SELECT (STRTOSET('[Department].[Department Description].&[ Department C]', CONSTRAINED) ) ON COLUMNS
       FROM [MultiValueDimension])



As you can see all locations are shown (even the one that has no relation with department C) . Not a desired situation

Option 2:
The next thing i tried is the following query:

SELECT [Measures].[Test Fact Count] ON 0,NONEMPTY([Location].[Location Description].[Location Description].MEMBERS) ON 1FROM
( SELECT (STRTOSET('[Department].[Department Description].&[ Department C]', CONSTRAINED) ) ON COLUMNS FROM [MultiValueDimension])



Resulting in :




Also not a desirable situation here...

Option 3
Someone on the MSDN forum pointed me to a extra parameter of the nonempty() function. The nonempty() function has the following syntax:  NONEMPTY(set_expression1 [,set_expression2]) and set_expression2 is a sort of limitation of the first set_expression. So the function returns a set of tuples that are not empty, based on the cross product of the second set.

So the final solution for getting the right information is this:

SELECT [Measures].[Test Fact Count] ON 0,NONEMPTY([Location].[Location Description].[Location Description].MEMBERS, [Measures].[Bridge Location Department Count]) ON 1FROM
( SELECT (STRTOSET('[Department].[Department Description].&[ Department C]', CONSTRAINED) ) ON COLUMNS FROM [MultiValueDimension])
 


So i'm using the bridge count of the bridge table for getting the right information. When this value is nonempty it does show me the locations and facts that are related. With this MDX query i can produce the following information:


Conclusion
With this solution you can simulate joining in SQL for getting the right information.

Greetz,
Hennie

donderdag 23 juni 2011

SSAS/Kimball : building a multivalue dimension construction in SSAS (part II)

In my former post i'll already explained the background for this post. If you didn't read this than i would advice reading this first post before reading this article. In this article i'll explain about building a multivalue dimension in SSAS (MM dimension). This post covers the following subjects:

  • Prerequisites.
  • Building a cube.

    Prerequisites
    Below you can see a script i've been using for building a cube. At the end of the script i've added a couple of facts/events.  So when we will quering this cube the following results should be shown for departments:
    • Department A : 3
    • Department B : 2
    • Department C : 2

    And for the locations:
    • Location 1 : 1
    • Location 2 : 2
    • Location 3 : 2

    First create a database and execute the following script:

    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TestFact]') AND type in (N'U'))
    DROP TABLE [dbo].[TestFact]
    GO

    CREATE TABLE [dbo].[TestFact](
        [TestFactID] [int] IDENTITY(1,1) NOT NULL,
        [FK_Date_Key] [int] NOT NULL,
        [FK_Location_Key] [int] NOT NULL,
        [TestFactCount] [int] NOT NULL
    ) ON [PRIMARY]
    GO

    ----
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Location]') AND type in (N'U'))
    DROP TABLE [dbo].[Location]
    GO

    CREATE TABLE [dbo].[Location](
        [Location_Dim_key] [int] NOT NULL,
        [Location_Code] [int] NOT NULL,
        [Location_Description] [varchar](50) NOT NULL
    ) ON [PRIMARY]
    GO

    ----
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Department]') AND type in (N'U'))
    DROP TABLE [dbo].[Department]
    GO

    CREATE TABLE [dbo].[Department](
        [Department_Dim_key] [int] NOT NULL,
        [Department_Code] [int] NOT NULL,
        [Department_Description] [varchar](50) NOT NULL
    ) ON [PRIMARY]
    GO

    ---
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Bridge_Location_Department]') AND type in (N'U'))
    DROP TABLE [dbo].[Bridge_Location_Department]
    GO

    CREATE TABLE [dbo].[Bridge_Location_Department](

        [Bridge_Location_Department_ID] [int] IDENTITY(1,1) NOT NULL,
        [FK_Location_Key] [int] NOT NULL,
        [FK_Department_Key] [int] NOT NULL,
        [Valid_From] [date] NOT NULL,
        [Valid_Until] [date] NOT NULL
    ) ON [PRIMARY]
    GO

    ---
    IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DimDate]') AND type in (N'U'))
    DROP TABLE [dbo].[DimDate]
    GO

    CREATE TABLE [dbo].[DimDate](
    [Date_dim_key] [int] NULL,
    [Date_Year] [int] NULL
    ) ON [PRIMARY]
    GO

    ---

    INSERT INTO dbo.Department (Department_Dim_key, Department_Code, Department_Description)
    VALUES (1, 1, ' Department A' ),(2, 2, ' Department B' ), (3, 3, ' Department C')

    INSERT INTO dbo.Location (Location_Dim_key, Location_Code, Location_Description)
    VALUES (1, 1, ' Location 1' ),(2, 2, ' Location 2' ), (3, 3, ' Location 3')

    INSERT INTO dbo.Bridge_Location_Department (FK_Location_Key, FK_Department_Key, Valid_From, Valid_Until)
    VALUES (1, 1, '2011-01-01', '9999-12-31' ),
    (2, 1, '2005-01-01', '9999-12-31' ),
    (2, 2, '2005-01-01', '9999-12-31' ),
    (3, 3, '2005-01-01', '9999-12-31' )

    INSERT INTO dbo.DimDate
    VALUES (1,2000),
    (2, 2001),
    (3, 2002),
    (4, 2003),
    (5, 2004),
    (6, 2005),
    (7, 2006),
    (8, 2007),
    (9, 2008),
    (10, 2009),
    (11, 2010),
    (12, 2011),
    (13, 2012),
    (14, 2013),
    (15, 2014),
    (16, 2015)


    INSERT INTO [MultiValueDimension].[dbo].[TestFact]
               ([FK_Date_Key]
               ,[FK_Location_Key]
               ,[TestFactCount])
    VALUES
               (7, 1, 1),
               (7, 2, 1),
               (8, 3, 1),
               (9, 3, 1),
               (9, 2, 1)


    Building a cube
    Okay, now we have to build a cube based on the tables created in SQL Server. Kimball calls this a multivalue dimension (actually it's a variant on the multivaluedimension, in my opinion). Microsoft calls this a many-to-many dimension (MM). Marc Russo published a great whitepaper on this subject. Many-to-many dimension (MM) is a better name for this subject. What can we say about Many-to Many dimension construction in relation to the case we are building:
    • There are two measure groups needed.
    • There are two dimnsions needed.
    • The bridge Location Department table will be Intermediate Measure Group. The intermediate Measure Group is the measure group that relates the MM dimension to the regular dimension In this case it relates the location to the department dimension.
    • Location is the intermediate dimension.


    Designing this in the cube designer shows this picture:



    So how does this looks in the dimension usage tab of the cube designer?


    As said earlier in the post: location and department are the dimensions. Testfact and the bridge location department table are the measure groups. So when we check the results in the browser we see the following results for the locations:


    And for the departments:


    The total is still 5 but adding the departments subtotals manually is equal to 7!!!

    And this is as predicted at the beginning of this post. So we have reached nirvana. Well not quite yet. What about history?  What if a location do not exist anymore between departments and locations? What if locations shift from locations to other departments? You want to count your facts at right departments in a correct timeline! I'll blog about this in the future.

    So, this is it for now.

    Greetz,
    Hennie

    vrijdag 17 juni 2011

    SSRS : Setting up a A4 page in Reporting Services

    Hi,

    I'm always a bit rusty when i start building reports in Reporting Services after a while. One thing i always has to figure out is how to set up the page size, body and margins. In a article on Microsoft you can find more information about this subjct. You can set the properties in the properties window or you can set the properties with report properties window (Menu -> Report -> Report properties). The relation between page, body, header and footer looks conceptual like the diagam below.


    Below you can see how i manually set the page size of the report with A4 paper settings.


    And don't forget to set the body properties:


    The formula of setting the PageSize Width, bodysize and margins is this: Page Width = Body Width+ Left margin + Right Margin. In my case 21= 19+1+1.

    In case of the height of the report you need to set the pagesize. In case of A4 : 29,7cm. In case of the body height you can set whatever you wan't. By setting the PageSize Height property the height of A4 is maintained and when the body height is larger than the pageSize (minus top margin and bottom margin) more pages are displayed/printed.

    It's also possible to set the properties with the report properties window. Below you can see an example in inches.



    We end up with the follow values for the proprties:



    Greetz,

    Hennie