I have a requirement for a cube that I find basic but I struggle to find a solution to it.
I have an Order Fact, an Order Line Fact and a Product Dimension.
Order Fact contains the different amounts for the order
Order Line Fact contains the different amounts for a particular line of an order, this is where we find the key to the Product Dimension
When a Product Category is selected, I need to be able to return from the Order Line Fact (because only this table has a link to Product Dimension) the total amount of the Order Fact for each order line that has a match on the Product Category.
For example :
Order 1 -> 100$
Order 1, Line 1 : Category FOO -> 30$
Order 1, Line 2 : Category BAR -> 20$
Order 1, Line 3 : Category FOO -> 50$
Order 2 -> 45$
Order 2, Line 1 : Category FOO -> 45$
If I do a simple query like the following should return me 100$ :
SELECT
[Measures].[X] ON 0,
[Product].[Category].&[BAR] ON 1
FROM Cube
And querying the FOO category should return 145$ :
SELECT
[Measures].[X] ON 0,
[Product].[Category].&[FOO] ON 1
FROM Cube
So I need to link my Orders to the Products in some way in link my Order Lines to my Orders. I have added the Order Amount and Order Number to each Order Line Fact but I'm lost as to how I can use them with a calculated member to fulfill my need.
There are a couple of ways you can approach this. Either way, I'm not seeing where you need a calculated member to meet your needs. They happen to have this exact scenario in the AdventureWorks 2012 Multidimensional Cube.
They have one Sales Order dimension that includes both the order number and order line. They have these as individual hierarchies and they put them together in a user hierarchy as well.
Then they created a single Sales Order measure group for the amount (at the order line level). They related this to both the Sales Order Dimension and the Product Dimension. This allows you to get the total for the order or the total for a specific product category.
You can download the AdventureWorks 2012 MD cube here and take a look for yourself.
Related
For a project I'm working on, I need to be able to communicate the quantity available to 'make' for a BOM item based on its contents. I won't go in-depth as to how this will be communicated, the base is in the SQL query.
The idea is fairly simple;
a BOM (Bill Of Material, indicating that it requires to be created) item (let's call this BOM1) has 1 or more stockitems linked to it. Having a quantity of 1 or higher. In this example let's take ITEM1 (3 units) ITEM2 (2 units) and ITEM3(5 units). Naturally, all of this is stored in a single table for referencing;
Secondary to that, there's the quantity in stock for each part within that BOM. this is stored in a 'bin content' table, example as below;
The sum of the stock, per item, is then summarised as below;
Now, based on the 'contribution' of each item to the BOM item, you can calculate the maximum available number to create;
in this scenario, based on ITEM3, I can create a maximum of 8 of item BOM1 as this has the lowest contribution (for lack of a better word I guess). Let's assume that parts can only be used once for a BOM item.
I can create a query for a single BOM item using a TOP 1 and ORDER BY ASC statement, the problem is that I have multiple BOM items, each having its own parts with multiple bin locations;
select TOP 1
BOM_ITEM.ITEM_NO
, (SUM(BIN_CONTENT.QTY) / BOM_ITEM.PART_ITEM_QTY) as AVAIL_TO_MAKE
from BOM_ITEM
JOIN BIN_CONTENT
ON BOM_ITEM.PART_ITEM_NO = BIN_CONTENT.ITEM_NO
WHERE BOM_ITEM.ITEM_NO = 'BOM1'
GROUP BY
BOM_ITEM.ITEM_NO
ORDER BY AVAIL_TO_MAKE ASC
So, based on the BOM item, I want to retrieve only the part item qty with the lowest 'contribution' so to communicate the theoretically available quantity to make, I just can't figure it out though.
any suggestions would be greatly appreciated!
The below query computes for each BOM item, how many items can be created given the available stock.
The query uses subquery to compute the stock across all bins. The main query groups by BOM item. For each BOM item, the minimum available to make is used. Additionally, the floor function is used to round down to an integer value.
WITH STOCK
USING (
SELECT ITEM_NO, SUM(QTY) AS QTY
FROM BIN_CONTENT
GROUP BY ITEM_NO
)
SELECT BOM_ITEM.ITEM_NO AS BOM_ITEM_NO,
FLOOR(MIN(STOCK.QTY / BOM_ITEM.PART_ITEM_QTY)) AS AVAIL_TO_MAKE
FROM BOM_ITEM
JOIN STOCK ON STOCK.ITEM_NO = BOM_ITEM.ITEM_NO
GROUP BY BOM_ITEM.ITEM_NO
I have made a simplified example to illustrate the question i'm trying to ask here. In my example i have sales orders and each sales order has multiple lines, i group by Sales Order Number, then by Sales Order Line (row groups)
I have found Group Filters very useful/flexible in filtering report data in specific areas of a table, so in my example i filter the SOLine group to exclude the SO line if it equals 3.
Then, i want to have a group aggregate for the entire SO, to tell me a count of the SO lines within it. Unfortunately when doing COUNT() expression from a textbox within the Sales Order Number group scope it counts all the lines, including the SO Line 3, whereas i want it to take into consideration the line filtered out from its child group.
Below is a screenshot of my tablix and grouping:
On the SOLine group i have the following filter:
And below is the output i get when previewing the report:
I want that count to evaluate to 4, but i ideally want to keep using groups as i've found they are much more efficient than using SUM(IIF) which completely slowed down my actual report which has thousands of rows.
If this is not possible, please give all best alternatives i could use.
Many thanks.
Jacob
We are trying to write a query to find out how much of the order was fullfilled in the first invoice on that order. Look at ArTrnInvoice table for Invoice info and OrderDetail for orders info. Compare qty ordered on each sales order line to what was fulfilled on the first invoice on that order
We tried
select case when SalesOrderLine>0 THEN QtyInvoiced /MOrderQty *100 Else End as Order_fILL_RATE FROM OrderDetail a Left JOIN
OrderHeader b ON a.SalesOrder = b.SalesOrder
WHERE b.Order Status ='9'
Basically,Trying to Output :
How much of the order was fullfilled in the first invoice - Let' say I ordered 2000$ worth of items. And Business Org invoiced this to me in two parts. First 1800$ within 10 days and then another 200$ later (or didn't ship this at all). In this case fill rate = 90%
Given Conditions
We have sql server 2012. Trying to calculate Fill Order Rate Using Order Line Item.
We have 3 table which consist of OrderHeader Info,OrderDetail Info, Invoice info table .
Structure of these tables are Here in link:
OrderDetail Table
Structure is
OrderHeader Table DDL
Also OrderStatus='9' means Fulfilled Order.
Any help on it would be much appreciated ?
I think I have a designs issue (dimensional modelling). What I have:
Dimensions: Person, Brand, Market, Order Date Time Base (Role Playing), PersonDecile (Outrigger)
Facts: Sales
All the Dims relate to the fact table. I have a calculation on PersonDecile which is a distinct count of all customers.
What I need to know\want:
I want to be able to get that count of person from PersonDecile and be able to split it using the brand and market desc. Currently it isnt doing that when I bring the brand desc in the browser, it instead replicates that count for both brands.
I have cube which contains geographic sales data. I want to pull sales of product items from all stores, based on the top 5 sellers from an arbitrary known store (BTW this is a simplified version of the real issue).
In sql (shame on me) this would be
select StoreId, ProductId, Sales from cube where ProductId in
(select top 5 ProductId from cube where Store = #Store order by Sales desc)
You can use the Topcount function for this. Provided you have dimensions named Product and Store and a measure named [Sales]:
Select [Measures].[Sales] On Columns,
CrossJoin([Store].Members,Generate(Topcount(Crossjoin({[Store].#[<StoreId>]},[Product].Members),5,[Measures].[Sales]),[Product].CurrentMember)) On Rows
From [Yourcube]
Replace <StoreId> with the specific store you're interested in. Generate will loop through the top 5 found for the specific store and return only the Product members. This result is then crossjoined with all the stores.
This will extract the top 5 products for your-store in ROWS axis and then select the [Sales] of these products according to the defaultMember of the [Store] dimension. In case [Store] defaultMember is the root of an aggregatable hierarchy this should give the sales of each product over all the stores.
SELECT
[Measures].[Sales] ON 0,
TopCount( [Store].[your-store] * [Product].Members ), 5, [Measures].[Sales] ) ON 1
FROM [your-cube]