How do I create hierarchies across dimensions? - ssas

I am using a snowflake design because I do not have huge volumes of data to worry about.
I have a Categories table and a Subcategories table and a Product table and from these tables I create a dimension with a
Category > Subcategory > Product
hierarchy.
I also have a Territory table, Country table, and a Customer table from which I create a dimension with a
Territory > Country > Customer
hierarchy.
This all works well, but what if I want to create other hierarchies, such as:
Territory > Country > Category > Subcategory > Product
or
Category > Customer > Product
or any other possible combination that the client wants to see.
I am unclear on how to do this with my existing table set.
Please ask for more information if I have not been clear.

This is not possible without making major changes in the cube design.
If you build an additional dimension which combines both dimensions into one.
You can achieve this. In this case you end up with 3 dimensions instead of 2.
To combine 2 dimensions, for each lowest level key combinations of both dimensions you need to create a new artificial key as the lowest key of the new dimension.
Then you can create the new attributes/hierarchies as usual.
Afterwards you can create a new unnatural hierarchy combining levels from unrelated hierarchies/attributes. This is what you want to achieve.
Since this new hierarchy will be unnatural, it will not perform very well but it will work.
Actually having 3 dimensions will not be necessary, after you combine 2 of them into a new one. You can get rid of the original 2 dimensions, since you can achieve the same functionality with the new one.

Related

Normalize a table with tightly coupled data

I currently have a table that stores the materials used to create an item
Item (material1, material2, material3)
Another material has recently been added. However, I want to normalize this table so that in the future, adding a new material won't need a new column to be added to the database. I extracted the materials into the following junction table
ItemJuncMaterial (id, itemId, materialid)
However, the catch is that the order of the materials matter. So this junction table won't allow me to run this query based on materials to get the item
select itemid from ItemJunMaterial where materialid in (1,2,3)
This can return items that use 2,3,1 or could even use two materials 1,2. Is there a better way to split up this table to normalize it and make it more dynamic?
You should consider a "bill of materials" (BOM) pattern (see here or here). The intersection of a BOM can include extra information about the composition, such as quantity of each component. You could easily include the sequence or priority of the component in that intersection just as easily.

SSAS - relationship/granularity

I have 2 fact tables with a measure group each, Production and Production Orders. Production has production information at a lower granularity (at the component level) productionorders has information at a higher level (order level with header quantities etc.).
I have created a surrogate key link between the two tables on productionorderid. As soon as I add Prod ID (from productiondetailsdim) to the pivot table it blats out the actual qty (from prod order measure group) and I cannot combine the qty's from the two measure groups.
How can I design the correct relationship between the two? Please see my dim usage diagram. Production Details is the dim that links the two fact tables, at the moment DimProductionDetails is in a fact relationship with Production. I'm not sure what the relationship should be with Production Order (it is currently many to many).
Please see example data between the two tables:
I have to be able to duplicate this behaviour:
Do you want the full actual qty from prod order measure group to repeat next to each product? If so a many-to-many relationship is right. I suspect once I explain how that many-to-many works you will spot the problem.
When you slice full actual qty from prod order measure group by product from the Production Details dimension it does a runtime join between the two measure groups on the common dimensions. So for example, if for if order 245295 has a date of 1/1/2015 while the production details for order 245295 have dates of 1/8/2015 then the runtime join will lose rows for that order and actual qty will show as null. So compare all the dimensions used on both measure groups and ensure all rows for the same order have the same dimension keys for those common dimensions. If for example dates differ then create a named query in the DSV that selects just the dimension columns from the production fact table which match the order fact table. Then create a new measure group off that named query and use the new measure group as the intermediate measure group in your many to many dimension. (The current many to many cell in the dimension usage tab should say the name of the new measure group not the existing Production measure group.)
Edit: if you want the actual qty measure to only show when you are at the order level and be null at the product level then try the following. Change the many-to-many relationship to a regular relationship and in the dialog where you choose how the fact table joins to the dimension change the dimension attribute to ProductionOrder_SK (which is not the key of the dimension) and choose the corresponding column in the fact table. Then left click on the Production Order measure group and go to the Properties window and set IgnoreUnrelatedRelationships to false. That way slicing actual qty by work center or by an attribute that is below grain in the Production Details dimension will show as null.

SSAS - Is there a way to have a dimension relate to a fact table based on two columns in the fact table?

In SSAS is there a way to have a dimension relate to a fact table based on two columns in the fact table?
We have two tables: Location (Dimension) and Sales (Fact). The Location dimension has one column: "state". The Sales table has three columns: "saleAmount", "customerState" and "billingState" (because our customer can be in California but wants us to bill a company or branch in New York).
In SQL, if we want to see all the sales in California, we write our SQL query as:
select sum(saleAmount) from Sales where customerState = 'California' or billingState = 'California'
Is there a way to accomplish this in SSDT when building my cube so that when I'm using Excel as an end user tool and I select the state attribute from the Location dimension and the saleAmount measure, the saleAmount will be based on customerState or billingState? (I do not want to have role playing dimensions here - where one Location dimension is based on customerState and another Location dimension is based on billingState. I want one dimension matching up with both columns at once.)
Not the way you're thinking, but you can achieve what you want by doing this:
Create a view on your fact table, that is a UNION of facts related to customerState and facts related to billingState. This means the view will only have 1 State column, and if a fact has different values for customerState and billingState, then it will have two rows in the view.
Use the view instead of your table to populate your measure group in the cube.
Link the measure group to the Location dimension on the single State column in the Fact view.
Builder beware, this results in duplicate counting of facts when rolling up states where a single fact is in two different states.

Customer Dimension as Fact Table in Star Schema

Can Dimension Table became a fact table as well? For instance, I have a Customer dimension table with standard attributes such as name, gender, etc.
I need to know how many customers were created today, last month, last year etc. using SSAS.
I could create faceless fact table with customer key and date key or I could use the same customer dimension table because it has both keys already.
Is it normal to use Customer Dimension table as both Fact & Dimension?
Thanks
Yes, you can use a dimension table as fact table as well. In your case, you would just have a single measure which would be the count - assuming there is one record per customer in this customer table. In case you would have more than one record per customer, e. g. as you use a complex slowly changing dimension logic, you would use a distinct count.
Given your example, it is sufficient to run the query directly against the Customer dimension. There is no need to create another table to do that, such as a fact table. In fact it would be a bad idea to do that because you would have to maintain it every day. It is simpler just to run the query on the fly as long as you have time attributes in the customer table itself. In a sense you are using a dimension as a fact but, after all, data is data and can be queried as need be.

SSAS Aggregation on Distinct ID

I wish to change the default aggregation from SUM to SUM on Distinct ID Values.
This is the current behaviour
ID Amount
1 $10
1 $10
2 $20
3 $30
3 $30
Sum Total = $90
By default, I am getting a sum of $90. I wish to do the sum on distinct ids and get a value of $60. How would I modify the default Aggregation Behavior to achieve this result?
Design your data as a many-to-many relationship: create one table/view having one record per ID and the amount column from the data shown in your question (the main fact table), and one table/view having one record per record of your data as shown in your question, presumably having another column, as otherwise it would not make any sense to have the data as shown in your question). This will be the m2m dimension table. Then, create a bridge table/view having the id of the m2m dimension table and your ID column.
Then create the following AS objects: A measure group from the main fact table, a dimension on column ID of the same table (in case there is no other column making a dimension table meaningful, in that case, you would better have a separate dimension table having ID as the primary key). Create a dimension from the m2m dimension table, and a measure group having only the invisible measure "count" from the bridge table. Finally, on the "Dimension Usage" tab of Cube Designer, set the relationship between the m2m dimension and the main measure group to be many to many via the bridge measure group.
See http://technet.microsoft.com/en-us/library/ms170463.aspx for a tutorial on many-to-many relationships.