List Dimension Members if selected date falls between Start Date and End Date in fact records SSAS MDX - sql

I have a fact table that contains invoice line items, and since these line items are subscriptions, there is a Start Date and an End Date involved
LineItem Customer Product OrderDate StartDate EndDate
1 Customer A Product A 1/1/2013 1/1/2013 3/1/2013
2 Customer A Product B 1/1/2013 1/1/2013 4/1/2013
3 Customer B Product A 1/1/2013 2/1/2013 6/1/2013
The client wants a list of Active Customers for a selected date in Excel(PivotTable). They want to select a date, and if the date falls between the Start Date and End Date of any Invoice Line Item record, then the Customer should be displayed. For example:
If '1/5/2013' is selected, the Customer List should return (LineItem: 1, 2):
Customer A
If '2/10/2013' is selected, the Customer List should return (LineItem: 1,2,3):
Customer A
Customer B
If '5/15/2013' is selected, the Customer List should return (LineItem: 3):
Customer B
Next, the client wants to filter by Products as well, so:
If '3/20/2013' is selected and Product A is selected, the Customer List should return (LineItem: 3):
Customer B
In SQL this is very easy:
Select Distinct Customer from Fact where #SelectedDate between StartDate and EndDate
I am unsure on how to approach this problem in SSAS and what to do with the 'Selected Date' as in, should this be another dimension? if so how is it going to relate to the Fact Table?
Or can this be done on Excel/PowerPivot side using in some other way?
Also my initial approach is to create a Named Set of customers - but I am not sure how to create it based on date range etc.
Any help will be appreciated!
Thanks

If you are able to write the MDX, then you can do this as follows, assuming there is a date dimension table with two foreign keys to it from the fact table, the role playing dimensions are named [Start Date] and [End Date], and #SelectedDate is a string matching the format of your date keys:
SELECT {}
ON COLUMNS,
[Customer].[Customer Name].Members
ON ROWS
FROM [Cube]
WHERE (null : StrToMember('[Start Date].[Date].[' + #SelectedDate + ']'))
*
(StrToMember('[End Date].[Date].[' + #SelectedDate + ']'): null)
The WHERE clause is a cross product of two sets: one set of start dates that contains all from the first one appearing in the dimension to the selected date, and one of end dates that contains all end dates from the selected date to the last one in the cube.
However, I do not think it is possible for users to get Excel to run this type of statement somehow, except via a VBA or Excel plugin solution. I think that should be possible, but have no experience with that.

Related

I need an SQL query to sum all items in an SQL between a specific data range

I need an sql query that will sum the sales of all products sold, by product, within a specific date range. Column "Product" Contains all product items. Column Date contains the date the item was sold and column value contains the actual sales value. So the result should contain just 2 columns, one for the product Name and one for the value, and several rows, which will show the sales total of each product item.
Are you just looking for GROUP BY with filtering?
select product, sum(sales)
from t
where date >= #date1 and date <= #date2
group by product;

Issues excluding data in SSAS cube (different output in SSMS and SSAS using EOMONTH())

I'm creating a cube whose stock values should only conclude the last day each month's balance and value.
Hence, I've created the following Query in SSMS:
Create table #theStockTable(
Stock int,
StockValue INT,
DateKey int
)
INSERT INTO #theStockTable
VALUES(3,5, 20170211),
(3,5,20170228),
(1,4,20170331),
(1,4,20170330)
SELECT CAST(CONVERT(varchar, DateKey, 112) AS numeric(8, 0)) AS DateKey, SUM(Stock) AS [CL Stock], SUM(StockValue) AS [CL Stock Value]
FROM #theStockTable
WHERE CONVERT(date, CONVERT(varchar(10), DateKey)) = eomonth(CONVERT(date, CONVERT(varchar(10), DateKey)))
GROUP BY DateKey
In SSMS this returns the correct values:
DateKey CL Stock CL Stock Value
20170228 3 5
20170331 1 4
However, when I create an OLAP cube using SSAS, and use the Query above as the Named Query for my fact table #theStockTable and the same Query as my only partition of the same fact table and deploy and execute the cube, I have a situation where I get different values on each day of every month, but I only want to have the values for each month's last day.
I have used New Project.. -> Import from Server (multidimensional model or data mining model) in SSAS. It is important that the users must be able to browse the cube as they presently do.
The cube whose meta data I have copied contains every day's values on the stock table. May there be some metadata change I need to make in addition to the Query modification I have done in Edit named Query.. in Data Source View and replacing the old Query in the partition with my new Query?
Hopefully someone can shed some light into this.
EDIT
To clarify my request, some users of the cube has explained that it is rather slow to browse in for instance Excel, mainly because my Stock measure is much bigger than it is required to be. As it is now, it returns every StockValue and Stock of each product and each day. I want to only include the total balance of StockValue and Stock of the last day of the month. All other stock values are redundant.
For instance, browsing my DimDate dimension table with the measurements Stock and StockValue should have this return set:
DateKey Stock StockValue
20170131 0 0
rather than the whole return set which is returned now:
DateKey Stock StockValue
20170101 3 5
20170102 4 6
20170103 1 1
20170131 0 0
I think you already had a date dimension in your cube, if yes, then follow these steps:
Add an additional attribute [IsLastDay] with value 0/1 in the date dimension to indicate if the current date record is the last day of that month or not.
2.Add a calculate measure [CalStock] with this formular:
([Measures].[StockValue],[Date].[IsLastDay].&[1])
3.Fire this query to return the expected result:
select {[CalStock]} on 0,
non empty{[Date].[Date].[Date]} on 1
from [YourCube]

AR Aging DAX Pattern

I'm trying to create a measure that displays buckets of AR values from our accounting system. The billing table is structured in a way where a row is created for each financial transaction related to a bill: one record shows the billed amount and a separate record, related by a bill key, shows one or more payments to the bill. I am able to create multiple measures that sum the bill amounts and break these out by Current, 30, 60, 90 and 120 day buckets (admittedly, this is new to me so even this measure might not be right):
AR Current =
VAR EndDate = TODAY()
VAR StartDate = EndDate - 29
RETURN
CALCULATE(
[Billings],
DATESBETWEEN(
'Date'[Date], StartDate, EndDate
)
)
The issue I have is trying to sum up the collections. The collections are not aged, but the total amounts collected for a specific bill need to be subtracted from the total billings in each aging bucket. Regardless of the date range, I need to get a list of all Bill Keys for each bucket, use those keys to sum the values for the Collections column, and subtract from the total within a bucket.
The only equivalent I can think of is a SQL query:
--This example gets the billed amount for anything less than 30 days old)
SELECT BILLKEY, SUM(BILLAMOUNT) BILLAMOUNT
FROM tblBilling
WHERE BILLDATE BETWEEN GETDATE()-30 AND GETDATE()
GROUP BY BILLKEY
-- This gets the corresponding collections:
SELECT BILLKEY, SUM(COLECTION) COLLECTION
FROM tblBilling
WHERE BILLKEY IN (
SELECT BILLKEY FROM tblBillings WHERE BILLDATE BETWEEN GETDATE()-30 AND GETDATE()
)
GROUP BY BILLKEY
Any help would be greatly appreciated.
Thanks,
Eric

ACCESS SQL: multiple tables and form input issues

I have created two list boxes with dates in an Access form to allow the user to select a date range. The user can pick a date in the first list and a later date in the second list.
The form is called Supplier History, the first list (the "from" date list) is called List3 and the second list (the "to" date list) is called List5. [Edit: List0 in code below contains suppliernames]
The dates in these lists are obtained by merging two tables. The tables involve supplier data, one table called Item Master focuses on general information on the supplier, the second table called ZMCE has transaction data.
The goal is to calculate the average price that the supplier charges, over the selected date range. The price column InfoRecPrice is in table Item Master.
For example let's say the lists have the following dates
These come from table Item Master: this table has dates (in column DateStamp) 8/24/2015, 9/1/2015, 10/1/2015, 11/1/2015, 12/9/2015, 1/4/2016, 2/1/2016, 3/1/2016, 4/1/2016, 5/1/2016, 6/1/2016. Table ZMCE has all the other dates, in column PODate.
Let's say the user picks the highlighted dates. I want the code to calculate the average price (price is in item master) over that time period even though the exact highlighted dates are not in that specific table.
The code below gives me a blank output, no matter what dates I select (even if I select those that are exactly the dates in the item master table):
SELECT Avg([Item Master].InfoRecPrice) AS Expr1
FROM [Item Master]
WHERE ((([Item Master].DateStamp)>=[Forms]![Supplier History]![List3] And ([Item Master].DateStamp)<=[Forms]![Supplier History]![List5]) AND (([Item Master].SupplierName)=[Forms]![Supplier History]![List0]));

DAX model invoice running balance

I have a table with invoices and a table with payments. The Invoice table consists of invoice id, amount, invoice date, expiry date. The payment table consists of invoice id, amount, payment date. The invoice table have an active relationship with the date table on the expiry date column. The payment table have an active relationship with the invoice table on the invoice id columns.
I would like to be able to show the invoice balance on an arbitrary day. Ie if I filter the report or page on a particular date I'd like to see the acual balance on that day per invoice. Anyone know how to acomplish this without creating a new table and programmatically fill it with invoice balance per day entries?
Here you go:
InvoiceTotalAmount:=
CALCULATE(
SUM(Invoice[Amount])
,ALL(DimDate) // The active relationship between Invoice[ExpiryDate]
// and DimDate[Date] would cause this to only be valid
// on the expiry date - we don't want that.
)
PaymentTotalToDate:=
CALCULATE(
CALCULATE( // We'll manipulate the relationship in the inner
// CALCULATE() before modifying context based on it
SUM(Payment[Amount])
,USERELATIONSHIP(Payment[Date], DimDate[Date])
)
,FILTER( // Now that that we're looking at the right relationship to
// DimDate, we can alter the date range in context
ALL(DimDate)
,DimDate[Date] <= MAX(DimDate[Date])
// Here, we take all dates less than the latest date in
// context in the pivot table - current date if 1 date in
// context, else last of week, month, quarter, etc....
)
)
InvoiceBalanceToDate:=[InvoiceTotalAmount] - [PaymentTotalToDate]
If you're not utilizing that active relationship between Invoice[ExpiryDate] and DimDate[Date], I'd mark it as inactive and the relationship between Payment[Date] and DimDate[Date] as the active one. You could then dispense with the CALCULATE() and ALL() in [InvoiceTotalAmount] and the inner CALCULATE() in [PaymentTotalToDate].
My model diagram:
You probably want to create a measure in the date table that uses CALCULATETABLE function to calculate the remaining balance of an invoice on that day.
https://technet.microsoft.com/en-us/library/ee634760(v=sql.105).aspx