forcing SSAS respecting relationships between dimensions - ssas

with regard to the following question and the given response I have the following question:
I am facing the same issue, but creating a bridge table like mentioned above is no option in my case as I still need the separate dimensions for other operations and different analysis.
For budgeting reasons I have to show all customers even if they have no match with the fact table. Enabling the corresponding option in EXCEL obiously leads to a cross join of the selected dimensions resulting in a complete list of all customers in all countries, although not each customer exists in all countries.
Is there another altrnative to force SSAS respecting relationships defined?
Many thanks in advance for assistance.

Let’s say you have FactSales with CustomerKey, CountryKey, DateKey and SalesAmount. When you build a PivotTable in Excel with Customer and Country on rows and SalesAmount on columns it only shows customers with sales. If you set Excel to show rows with no data it shows all customers in all countries.
Try building a new FactCustomerCountry table with CustomerKey and CountryKey only. Create a measure Customer Country Count.
Then create a new calculated measure:
CREATE MEMBER CURRENTCUBE.[Measures].[Sales Amount with Zeros]
AS
IIF(
IsEmpty([Measures].[Customer Country Count]),
Null,
CoalesceEmpty([Measures].[SalesAmount], 0)
);
Use that measure in your PivotTable instead of SalesAmount. Do not show rows with no data. The measure should return meaningful Customer-Country combinations and should return all customers.

Hi you can solve your issue in MDX. Take a look at the query below, its an example on Adventureworks. This will fetch all the products that were sold and the quaters that they were sold in.Now some products were never sold, I still want to see those product.
select [Measures].[Internet Sales Amount] on columns,
--non empty
{filter(([Product].[Subcategory].[Subcategory],[Date].[Calendar Quarter of Year].[Calendar Quarter of Year]),[Measures].[Internet Sales Amount]>0),
filter(([Product].[Subcategory].[Subcategory],[Date].[Calendar Quarter of Year].defaultmember),[Measures].[Internet Sales Amount]=null)
}
on rows
from
[Adventure Works]

Related

Aggregate my quantity sum in a way that doesn't lead to the storeID repeating?

I am writing a SQL query that needs to show the total number of orders from each store. The issue I am running into, is that while I can figure out how to sum the orders by product and each product is only sold by one store, I can't figure out how to total the orders by store alone
This is the code I currently have
SELECT storeID AS [STORE], Product_ID
, SUM(quantity) AS [ORDERS BY STORE]
FROM Fulfillment, Store
GROUP BY storeID, Product_ID;
This line of code leads to a repeat of storeID in the results, where ideally, I would only want storeID to be included in the results once with the total quantity of all of Product_ID being included. I tried to remove Product_ID from the GROUP BY statement, but this resulted in the following error
Column 'Fulfillment.Product_ID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I'm new to SQL and am trying to learn, so any help and advice is greatly appreciated
#ZLK is correct that if your goal is a total number of units ordered ("quantity") of any product, simply remove the [product_id] column from the SELECT and GROUP BY.
However, it appears that you're referencing two tables ("FROM Fulfillment, Store") and not specifying how those tables are joined, creating a cartesian join - all rows in one table will be joined to all rows in the other table. If the [storeID] and [quantity] fields are available in the Fulfillment table, I recommend removing the Store table reference from the FROM clause (so "FROM Fulfillment" alone).
One last note: You mention that you want to count "orders". In some circumstances, an order may have multiple products and a quantity > 1. If your goal is the total number of "orders" regardless of the number of products or quantity of products on an order, you'll want to use "COUNT(DISTINCT orderID) as [Orders]" (where "orderID" is the reference to the unique order number).

Compare the sum of rows with shared reference in one table with a single value in another

I have a list of my stock in one table, stock, and I reserve portions of that stock to an order in another table, orders
I have a feeling my data is no longer in a good state, and I need to compare the amount I have reserved from a chunk of stock in the orders table to the total I have in the reserved stock table.
Each stockref has a unique entry in stock but can occur multiple times in orders if it represents a quantity that is split across multiple orders.
The ideal query would show me stockrefs that are over-reserved. Once I have these I can then check my code to see what caused the issue and fix it before I go bust selling items I no longer have stock of.
I think this should resolve your problem
Select s.reservedqty,s.stockref,O.Total_reservedqty from stock S join
(
Select sum(reservedqty) as Total_reservedqty,stockref from orders group by stockref
) O
On S.stockref=O.stockref
where O.Total_reservedqty !=s.reservedqty

Crystal 2016 pull from 2 unrelated tables in one report

I have searched and the only answers I found were for cross joining.
I have 3 tables that are related by 1 field only. I'm trying to pull data from 2 tables that are linked to the other table.
The first table contains salesman data IDnumber, name, address, phone number, hire date, wage, etc.
There is a sales table that contains salesmanIDnumber, date of sale, object sold, and price.
There is a purchases table that contains salesmanIDnumber, date of purchase, object purchased, and price.
The date fields in sales and purchases are unrelated. I know the easiest solution would be to have the sales and purchase table combined with a column for buy/sell, but I didn't create the database and I'm working with what I've got. basically I want to pull all purchases or sales by salesmanID in one report.
I have linked the salesman table to the sales table and the purchases table with left outer joins by the salesman ID. What I'm getting in results is cross join with each result from the purchase table displayed once for each result in the sales table, which gives me multiplied results instead of added. for example, 4 sales and 6 purchases would be 10 entries, but I'm getting 24 results.
I tried entering an example but the site stripped the spacing and pushed everything together basically making it unreadable.
how can I get it to show data from both tables independently?
I do have access to create views in the database if that's the best solution, but I'm not proficient at it.
Create 2 views (one for sales, the other for purchases), each Grouped By SalesMan.
Since each SalesMan would have only one row in each view, you can join them without record inflation.
Or use a UNION to append Purchase records to Sales Records, taking care of including a 'Type' column ('Sales' as Type, or 'Puurchases' as Type) and/or reverse sign on quantities to allow summarizing things in a logical.

Customer List with invoice which has all selected items

I have DimProduct table, DimCustomer table and FactSales table.
There is a targeted product list.
I want to list customers who buy all products of the targeted product list in one invoice.
How do I do it? I have no clue. Please give me some advice.
CustomersWithAllTargets:=
COUNTROWS(
FILTER(
DimCustomer
,CALCULATE(
DISTINCTCOUNT( FactSale[ProductKey] )
,TargetProduct
) = DISTINCTCOUNT( TargetProduct[ProductKey] )
)
)
Let's break this down.
COUNTROWS() does what it says and counts the rows in a table.
The table whose rows we want to count is the result of our FILTER(). FILTER() takes a table expression as its first argument, creating a row context by iterating over each row in that table expression. For each row, the expression in its second argument is evaluated. Only those rows in the table for which the second argument evaluates to true are included in the output.
Our table argument is DimCustomer. DimCustomer will be filtered by the pivot's filter context (e.g. if you select a subset of customers, only that subset will be considered).
For each customer, we evaluate the CALCULATE().
CALCULATE() evaluates its first argument in the filter context defined by its second through last arguments. We're counting the distinct values in FactSale[ProductKey] for the current customer (current in the iteration through each row from FILTER()), subject to the constraint that they exist in the table TargetProduct.
We are testing the value of that CALCULATE() (how many target products the current customer has bought), with the count of values in TargetProduct[ProductKey]. When they are equal, the customer has bought all products. When they are not equal, the customer hasn't.
So we'll return a table of customers who've bought all the target products. At the customer level in a pivot, this will return 1 or blank for each customer. Pivot tables automatically suppress the display of row labels with blanks for measures, so you'll only see the customers that have bought all the target products.
The grand total will tell you how many customers total have bought all the targets.
This will also support selecting subsets of TargetProduct, if you have different target groups.
Below is an image of my model and sample data, along with a pivot table showing the whole thing behaving appropriately.
Edit
We'll make use of one more function to be able to group by multiple fields, SUMMARIZE().
CustomersWithAllTargets:=
COUNTROWS(
FILTER(
SUMMARIZE(
FactSale
,FactSale[InvoiceKey]
,FactSale[CustomerKey]
)
,CALCULATE(
DISTINCTCOUNT( FactSale[ProductKey] )
,TargetProduct
) = DISTINCTCOUNT( TargetProduct[ProductKey] )
)
)
SUMMARIZE() takes a table as its first argument and a list of fields to group by. It can also add calculated columns and do rollups on those columns, but we don't need that. Newer versions of Power Pivot (Excel 2016) have a syntax-equivalent GROUPBY() that performs grouping for a potential (small) performance improvement. We simply group on InvoiceKey and CustomerKey and do the same filtering as before.
This does alter the nature of the return value. Previously the count would be the number of customers who've purchased the whole set of target products. Since we're now also grouping on invoice, the count will be of the number of customer-invoice pairs that have all targets purchased. Since your requirement was stated simply as listing the customers, this measure still meets them. You may see a number >1 for a specific customer, though. You will still have the behavior in a pivot of omitting the customers who don't meet the criteria.
Here's a picture of my altered sample data performing with this measure. Note that Customer6 now has purchased all three targets, but on separate invoices. Customer3 still shows up as all three are on 1 invoice.

SSAS best way to count Orders by number of Products ordered

I'm looking for the best way to implement measure that counts Orders by the number of products ordered.
There is a fact table of ProductsOrdered, like this
CREATE TABLE ProductsOrdered (
IdOrder UNIQUEIDENTIFIER,
IdProduct UNIQUEIDENTIFIER,
OrderDate DATE,
Quantity INT,
Price DECIMAL(18,2)
)
for every order there are rows in the table for every kind of product ordered.
I would like to have a measure that counts how many ordered a single product, how many 2, and so on.
Just like this SQL query does.
SELECT OrderedProductNumber, COUNT(IdOrder) AS NumberOfOrders
FROM (
SELECT IdOrder, COUNT(IdProduct) AS OrderedProductNumber
FROM ProductsOrdered
GROUP BY IdOrder
) t
GROUP BY OrderedProductNumber
Which MDX expression is best counterpart?
Thanks.
The problem you have is that you can only produce a count by a dimension. In this case, your dimension is the products ordered (1, 2, 3, etc.) Your option is to create a physical dimension that has the range of possibilities (tedious), or to create "dummy" members for a dimension to do the same thing as a calculation (tedious AND likely a performance problem). I would lean towards creating a dimension for products ordered, and then create a fact table using your SQL query and add the dimension and measure group to the cube. It's going to be easier to implement in the long run and by physically instantiating the counts, you will get much better query performance.
You can define dimension based on product
then measure group based on fact table, that you named ProductOrdered,
then you can define distinct count measure based on your IOrder column (e.g [IOrderdistinctcount])
after that you can use
select
{IOrderdstinccount} on 0,
[dim Product].[product].[Product].members on 1
from [Cube]