Showing posts with label cube. Show all posts
Showing posts with label cube. Show all posts

Friday, February 24, 2012

Condensing/Modularizing several cumulative calculated measures

In my cube, I have a number of calculated measures - around 30 per date tree and sales type combination (each different sales type has a different fiscal year). I have a Product.Sales Type attribute that can flicker the results between the different sale types, but the issue of working with different hierarchies is still present

Is there a way to condense this statement or somehow hookup some pieces so that one doesn't have to keep coding the same logic over and over? Either reducing the # of calculated members, or simply using some supported functionality to only code the logic in 1 spot, passing in the 'sale type' and 'measure name' and the inner logic would calculate the correct date tree and year level all within itself.

The pieces that change are bolded

(Date Tree hierarchy name,

Date Tree year level,

Calculated measure name

)

CASE

WHEN [Date].[Date Tree].CurrentMember.Level IS

[Date].[Date Tree].[(All)]

THEN [Measures].[Calculated Sales]

ELSE

Sum

(

PeriodsToDate

( [Date].[Date Tree].[Fiscal Year],

[Date].[Date Tree].CurrentMember

),

[Measures].[Calculated Sales]

)

END

One of my thoughts is to do something like this, but can someone feed me some ideas and fill in the syntax holes?

public [return type?] GetCumulativeMeasure( ‘Group 1’, ‘Calculated Sales 1’)

public [return type?] GetCumulativeMeasure(SalesType as string, MeasureName as string)

{

string Hierarchy = “”;

string HierarchyYearLevel = “”;

switch (SalesType)

{

case ‘Group 1’:Hierarchy = “[Date].[Date Tree]”; HierarchyYearLevel = Hierarchy + “.[Fiscal Year]”;

case ‘Group 2’:Hierarchy = “[Date].[Date Tree B]”; HierarchyYearLevel = Hierarchy + “.[Year Period]”;

}

//build calculated measure string to get a calculated measure for the year period and MeasureName variables

}

One thing you can do is create what's known as a 'time utility' or 'shell' dimension. There's a good writeup of what this means here:

http://www.obs3.com/A%20Different%20Approach%20to%20Time%20Calculations%20in%20SSAS.pdf

Incidentally, your use of the CASE statement to check what level you're at inside your calculation is not the most efficient way of writing the expression. Take a look at Mosha's blog entry on this subject for details on how you can use scoped assignments to do this instead:

http://sqljunkies.com/WebLog/mosha/archive/2006/10/25/time_calculations_parallelperiod.aspx

This might also reduce the amount of code you need to write.

HTH,

Chris

|||

Thank you for the links! It's always nice to know that there's a better way - I had a feeling about that as well, as things were too clunky.

|||

I've read over the material, but I can't picture how to put in mosha's suggestions into the mix.
Some date calculations I'd be doing are L30, L60, and Cumulative based on year.

The Last _ Days should only work with the Date level and always go back 30 days from the current membe,
while cumulative would be limited to the year that's being used.

I envision a shell dimension attribute with the following members:
L30 Days
L60 Days
MTD
LY MTD
YTD
LYTD
Yearly Cumulative

Could someone provide an example with a few of the calculations or let me know what other info would be helpful to post? Thank you for working with me through this process!!

|||

I think the logic you've already got in your calculations will stay pretty much the same; it's scoping the calculations that will be tricky. We'd need to know some details about your Date dimension structure.

Chris

|||

The date dimension hierarchy structure's right now are as follows. What more info is needed?

[Date].[Date Tree A]
Year Type A (spans from jan-dec)
Month
Day

[Date].[Date Tree B]
Year Type B (spans from march-july this year, then next year goes from Aug-July)
Month
Day

[Date].[Date Tree C]
Year Type C (spans from oct-sept)
Month
Day


Calculated measures include:

hierarchy based:
(Cumulative based on year and hard coded to a specific date tree)
Cumulative Type A Sales
Cumulative Type A Internet Sales
Cumulative Type B Sales
Cumulative Type B Internet Sales
Cumulative Type C Sales
Cumulative Type C Internet Sales

(hopefully obtainable in both hierarchy and non hierarchy form (from the Month or Day level):

LY MTD Type A Sales
LY MTD Type B Sales
LY MTD Type C Sales

MTD Type A Sales
MTD Type B Sales
MTD Type C Sales


Not hierarchy based:
L30 Days Sales
L30 Days Internet Sales
L60 Days Sales
L60 Days Internet Sales
(for these, I'm hoping to somehow just have a reusable 'L30' and 'L60' scoping, but that would allow you to see measures in both time periods in the same axis. If it's a good route to use a time shell dimension, then that's what I would do, but I'm looking for a little bit more instruction if possible.

Condensing/Modularizing several cumulative calculated measures

In my cube, I have a number of calculated measures - around 30 per date tree and sales type combination (each different sales type has a different fiscal year). I have a Product.Sales Type attribute that can flicker the results between the different sale types, but the issue of working with different hierarchies is still present

Is there a way to condense this statement or somehow hookup some pieces so that one doesn't have to keep coding the same logic over and over? Either reducing the # of calculated members, or simply using some supported functionality to only code the logic in 1 spot, passing in the 'sale type' and 'measure name' and the inner logic would calculate the correct date tree and year level all within itself.

The pieces that change are bolded

(Date Tree hierarchy name,

Date Tree year level,

Calculated measure name

)

CASE

WHEN [Date].[Date Tree].CurrentMember.Level IS

[Date].[Date Tree].[(All)]

THEN [Measures].[Calculated Sales]

ELSE

Sum

(

PeriodsToDate

( [Date].[Date Tree].[Fiscal Year],

[Date].[Date Tree].CurrentMember

),

[Measures].[Calculated Sales]

)

END

One of my thoughts is to do something like this, but can someone feed me some ideas and fill in the syntax holes?

public [return type?] GetCumulativeMeasure( ‘Group 1’, ‘Calculated Sales 1’)

public [return type?] GetCumulativeMeasure(SalesType as string, MeasureName as string)

{

string Hierarchy = “”;

string HierarchyYearLevel = “”;

switch (SalesType)

{

case ‘Group 1’:Hierarchy = “[Date].[Date Tree]”; HierarchyYearLevel = Hierarchy + “.[Fiscal Year]”;

case ‘Group 2’:Hierarchy = “[Date].[Date Tree B]”; HierarchyYearLevel = Hierarchy + “.[Year Period]”;

}

//build calculated measure string to get a calculated measure for the year period and MeasureName variables

}

One thing you can do is create what's known as a 'time utility' or 'shell' dimension. There's a good writeup of what this means here:

http://www.obs3.com/A%20Different%20Approach%20to%20Time%20Calculations%20in%20SSAS.pdf

Incidentally, your use of the CASE statement to check what level you're at inside your calculation is not the most efficient way of writing the expression. Take a look at Mosha's blog entry on this subject for details on how you can use scoped assignments to do this instead:

http://sqljunkies.com/WebLog/mosha/archive/2006/10/25/time_calculations_parallelperiod.aspx

This might also reduce the amount of code you need to write.

HTH,

Chris

|||

Thank you for the links! It's always nice to know that there's a better way - I had a feeling about that as well, as things were too clunky.

|||

I've read over the material, but I can't picture how to put in mosha's suggestions into the mix.
Some date calculations I'd be doing are L30, L60, and Cumulative based on year.

The Last _ Days should only work with the Date level and always go back 30 days from the current membe,
while cumulative would be limited to the year that's being used.

I envision a shell dimension attribute with the following members:
L30 Days
L60 Days
MTD
LY MTD
YTD
LYTD
Yearly Cumulative

Could someone provide an example with a few of the calculations or let me know what other info would be helpful to post? Thank you for working with me through this process!!

|||

I think the logic you've already got in your calculations will stay pretty much the same; it's scoping the calculations that will be tricky. We'd need to know some details about your Date dimension structure.

Chris

|||

The date dimension hierarchy structure's right now are as follows. What more info is needed?

[Date].[Date Tree A]
Year Type A (spans from jan-dec)
Month
Day

[Date].[Date Tree B]
Year Type B (spans from march-july this year, then next year goes from Aug-July)
Month
Day

[Date].[Date Tree C]
Year Type C (spans from oct-sept)
Month
Day


Calculated measures include:

hierarchy based:
(Cumulative based on year and hard coded to a specific date tree)
Cumulative Type A Sales
Cumulative Type A Internet Sales
Cumulative Type B Sales
Cumulative Type B Internet Sales
Cumulative Type C Sales
Cumulative Type C Internet Sales

(hopefully obtainable in both hierarchy and non hierarchy form (from the Month or Day level):

LY MTD Type A Sales
LY MTD Type B Sales
LY MTD Type C Sales

MTD Type A Sales
MTD Type B Sales
MTD Type C Sales


Not hierarchy based:
L30 Days Sales
L30 Days Internet Sales
L60 Days Sales
L60 Days Internet Sales
(for these, I'm hoping to somehow just have a reusable 'L30' and 'L60' scoping, but that would allow you to see measures in both time periods in the same axis. If it's a good route to use a time shell dimension, then that's what I would do, but I'm looking for a little bit more instruction if possible.

Condensing/Modularizing several cumulative calculated measures

In my cube, I have a number of calculated measures - around 30 per date tree and sales type combination (each different sales type has a different fiscal year). I have a Product.Sales Type attribute that can flicker the results between the different sale types, but the issue of working with different hierarchies is still present

Is there a way to condense this statement or somehow hookup some pieces so that one doesn't have to keep coding the same logic over and over? Either reducing the # of calculated members, or simply using some supported functionality to only code the logic in 1 spot, passing in the 'sale type' and 'measure name' and the inner logic would calculate the correct date tree and year level all within itself.

The pieces that change are bolded

(Date Tree hierarchy name,

Date Tree year level,

Calculated measure name

)

CASE

WHEN [Date].[Date Tree].CurrentMember.Level IS

[Date].[Date Tree].[(All)]

THEN [Measures].[Calculated Sales]

ELSE

Sum

(

PeriodsToDate

( [Date].[Date Tree].[Fiscal Year],

[Date].[Date Tree].CurrentMember

),

[Measures].[Calculated Sales]

)

END

One of my thoughts is to do something like this, but can someone feed me some ideas and fill in the syntax holes?

public [return type?] GetCumulativeMeasure( ‘Group 1’, ‘Calculated Sales 1’)

public [return type?] GetCumulativeMeasure(SalesType as string, MeasureName as string)

{

string Hierarchy = “”;

string HierarchyYearLevel = “”;

switch (SalesType)

{

case ‘Group 1’:Hierarchy = “[Date].[Date Tree]”; HierarchyYearLevel = Hierarchy + “.[Fiscal Year]”;

case ‘Group 2’:Hierarchy = “[Date].[Date Tree B]”; HierarchyYearLevel = Hierarchy + “.[Year Period]”;

}

//build calculated measure string to get a calculated measure for the year period and MeasureName variables

}

One thing you can do is create what's known as a 'time utility' or 'shell' dimension. There's a good writeup of what this means here:

http://www.obs3.com/A%20Different%20Approach%20to%20Time%20Calculations%20in%20SSAS.pdf

Incidentally, your use of the CASE statement to check what level you're at inside your calculation is not the most efficient way of writing the expression. Take a look at Mosha's blog entry on this subject for details on how you can use scoped assignments to do this instead:

http://sqljunkies.com/WebLog/mosha/archive/2006/10/25/time_calculations_parallelperiod.aspx

This might also reduce the amount of code you need to write.

HTH,

Chris

|||

Thank you for the links! It's always nice to know that there's a better way - I had a feeling about that as well, as things were too clunky.

|||

I've read over the material, but I can't picture how to put in mosha's suggestions into the mix.
Some date calculations I'd be doing are L30, L60, and Cumulative based on year.

The Last _ Days should only work with the Date level and always go back 30 days from the current membe,
while cumulative would be limited to the year that's being used.

I envision a shell dimension attribute with the following members:
L30 Days
L60 Days
MTD
LY MTD
YTD
LYTD
Yearly Cumulative

Could someone provide an example with a few of the calculations or let me know what other info would be helpful to post? Thank you for working with me through this process!!

|||

I think the logic you've already got in your calculations will stay pretty much the same; it's scoping the calculations that will be tricky. We'd need to know some details about your Date dimension structure.

Chris

|||

The date dimension hierarchy structure's right now are as follows. What more info is needed?

[Date].[Date Tree A]
Year Type A (spans from jan-dec)
Month
Day

[Date].[Date Tree B]
Year Type B (spans from march-july this year, then next year goes from Aug-July)
Month
Day

[Date].[Date Tree C]
Year Type C (spans from oct-sept)
Month
Day


Calculated measures include:

hierarchy based:
(Cumulative based on year and hard coded to a specific date tree)
Cumulative Type A Sales
Cumulative Type A Internet Sales
Cumulative Type B Sales
Cumulative Type B Internet Sales
Cumulative Type C Sales
Cumulative Type C Internet Sales

(hopefully obtainable in both hierarchy and non hierarchy form (from the Month or Day level):

LY MTD Type A Sales
LY MTD Type B Sales
LY MTD Type C Sales

MTD Type A Sales
MTD Type B Sales
MTD Type C Sales


Not hierarchy based:
L30 Days Sales
L30 Days Internet Sales
L60 Days Sales
L60 Days Internet Sales
(for these, I'm hoping to somehow just have a reusable 'L30' and 'L60' scoping, but that would allow you to see measures in both time periods in the same axis. If it's a good route to use a time shell dimension, then that's what I would do, but I'm looking for a little bit more instruction if possible.

Friday, February 17, 2012

Concurrent Cube Processing

Is it possible to have multiple incremental updates to the same cube or partition? We have imports into the same cube that would occurr at different times as the data from multiple business areas is processed and becomes available to the cube for processing.

Further to this, is it possible to query the cube when processing is taking place? If so, what data is visible? Is the data visible as each row is added to the cube or is it only available one the transaction is 'commited'.

This is quite important for us since it will define the partitioning and processing strategy.

No replies yet! I can't believe no one knows the answer to this...|||I haven't dealt with incremental updates, but (if you have Enterprise) you can have multiple measures/partitions/dimensions etc processing in parallel. (Via the UI you can click "Change Settings" to configure this. Is this what you're asking?

Re: whether you can query the cube while processing is occurring - in Harinath & Quinn's book, I vaguely remember a section where it stated that the existing measure groups stay online until the new one is created, though I can't say I've noticed this behavior (typically when I fully process a cube the old one is immediately thrown out :-( )|||

I was actually wondering if you can have multiple independent processes doing updates to the same cube, but in different partitions, whilst still being available for querying of the existing data.

Here is my scenario:

The company is a financial company with multiple business areas with independent systems. Each day a whole series of batch ETL processes are carried out to consolidate the data into a DW/Reporting Database. This happens at different times for different business areas and the time at which these happen are not predictable nor is the order set. The users want the data asap so we don't want to wait for the last data import to complete before starting to process the cubes/partitions. Hence, we want to create and process partitions on an ad hoc basis and at any time and concurrently with any other processing. I want to know if Analysis Services could handle this without barfing.

|||

If you design your partition strategy correctly such that a batch update of a given partition occurs and then you kick off an incremental update for that paritition and it completes before you need to kick off another incremental update for that same partition, then yes, SSAS can handle multiple partition processing transactions concurrently (in parallel). What I don't believe you can do is kick off multiple incremental update processes agains the SAME partition at the same time...

As for whether data is available or not, that depends on the type of processing you are doing. For incremental updates and for refresh data processing of a given partition, that partition's data remains online during the processing (as the processing is wrapped in a transaction that does not affect the existing partition structure until it commits). However, if you do a rebuild processing action on a partition, that partition (and its associated measure group) becomes unavailable as soon as the transaction starts and it is not available until the transaction completes. Here's a link to a white paper describing the various processing types available for various objects and the ramifications of each:

http://msdn2.microsoft.com/en-us/library/ms345142.aspx

HTH,

Dave Fackler

|||

Hi Dave,

Your last paragraph is not entirely accurate. Full processing can also be done in a transaction (in fact processing a single object is done in an implied transaction) and the old data will be available for querying while the processing is taking place and then at the end of the transaction the old data is swapped out and the new data is then made available. The difference with full processing is that dependant objects will become unprocessed.

So if you full process a dimension, all the cubes that use that dimension will become unprocessed at the end of the transaction (you could manage this by full processing the dimension and relevant cubes in a single transaction).

Tuesday, February 14, 2012

Conception of my cube

Hello,
During my internship, I had to create a cube for sales based on only one dB (of an ERP).
So I've created a view grouping information I need.
So I've only one "table" (a view actually) which is my fact table and my only dimension table.
Actually, the dimension are the attributes of my sole dimesion.

The problem is that I've to write my report and I don't know if I've made the good choice. I can also create a dimension table with Customer, for countries ... but the result would be the same.

Thanks in advance for your advices.

Hey there,

If you are happy with the performance, the SQL is maintainable and you will only ever have one cube for your company, then your solution will be adequate.

However, you may find that you run into performance, scalability and maintenance issues as your data grows and if you need to start working with other business processes (e.g. order processing or invoicing).

By having a single view you are bypassing some of the automated work a cube / Analysis Services can give you. Also with the view, you may end up replicating some logic for bringing back dimension values (e.g. country). If you were to have another view for a new cube, you would have to replicate all the SQL for extracting the country information to return in your flattened view.

By using dedicated dimension tables, you will gain re-use of dimension content (conformed dimensions), requiring only a single extract from the source system.

There are numerous other benefits of having a more structured data warehouse/data extract process, such as change tracking, referential integrity checking, introduction of surrogate keys (non source system dependent keys if you are dealing with multiple data sources).

Hope that made sense,

Jonathon