Set up - SSAS 2012 with OLAP cubes (built by supplier) and MS Report Builder v3. No access to BIDS.
I am building a report which needs to calculate a disposal rate based on data from a single cube. Historically this would have been calculated from two separate tables of data, giving a count by month of new items by date recorded and a count by month of items disposed by month of disposal. This can then be turned to a disposal rate using a lookup or similar.
Blank disposal dates are fine (can take months to dispose of items).
I would like to keep this in a single query so that I can introduce extra dimensions to analyse the data and represent it multiple ways easily. My suspicion is that I need a calculated member but I am not sure where to start with these. Any help would be greatly received - I am trying out a few things and will update this should I solve myself.
Simple formula would be
=(sumif(Items, DateReported="July 2014"))/(sumif(Items, Disposal Date="July 2014"))`
So the following data...
Month Recorded Month Disposed No of Items
May-14 May-14 25
May-14 Jun-14 3
May-14 Jul-14 45
Jun-14 232
Jun-14 Jun-14 40
Jun-14 Jul-14 46
Should produce...
Month No Recorded No Disposed Disposal Rate
01/05/2014 73 25 34%
01/06/2014 48 43 90%
01/07/2014 45 91 202%
My current MDX statement:
SELECT
NON EMPTY { [Measures].[No of Items] } ON COLUMNS,
NON EMPTY
{
([Date Reported].[Calendar Months].[Month].ALLMEMBERS
*
[Disposal Date].[Calendar Months].[Month].ALLMEMBERS )
} ON ROWS
FROM [Items]
You can use LinkMember to move a reference to one hierarchy (like [Date Reported].[Calendar Months]) to another one (like [Disposal Date].[Calendar Months]), provided both hierarchies have the exact same structure. Thus, only using [Date Reported] in your query, the calculation can use [Disposal Date]. The query would be like the following:
WITH MEMBER Measures.[Disposed in Date Reported] AS
(Measures.[No of Items],
LinkMember([Date Reported].[Calendar Months].CurrentMember, [Disposal Date].[Calendar Months]),
[Date Reported].[Calendar Months].[All]
)
MEMBER Measures.[Disposal Rate] AS
IIf([Measures].[No of Items] <> 0,
Measures.[Disposed in Date Reported] / [Measures].[No of Items],
NULL
), FORMAT_STRING = '0%'
SELECT { [Measures].[No of Items], Measures.[Disposed in Date Reported], Measures.[Disposal Rate] }
ON COLUMNS,
[Date Reported].[Calendar Months].[Month].ALLMEMBERS
ON ROWS
FROM [Items]
Possibly, you would want to adapt the column titles in your report. I left that out and used member names that desribe more what they do than what should be shown to users.
Related
I have data in 2 dimensions (let's say, time and region) counting the number of visitors on a website for a given day and region, as per the following:
time
region
visitors
2021-01-01
Europe
653
2021-01-01
America
849
2021-01-01
Asia
736
2021-01-02
Europe
645
2021-01-02
America
592
2021-01-02
Asia
376
...
...
...
2021-02-01
Asia
645
...
...
...
I would like to create a table showing the average daily worldwide visitors for each month, that is:
time
visitors
2021-01
25238
2021-02
16413
This means, I need to aggregate the data this way:
first, sum over regions for distinct dates
then, calculate average on dates
Is was thinking of doing a global average of all lines of data for each month, and then multiply the value by the number of days in the month but since that number is variable I can't do it.
Is there any way to do this ?
Create 2 calculated fields:
Month(time)
SUM(visitors)/COUNT(DISTINCT(time))
In case it might help someone... so far (January 2021) it seems there is no way to do that in DataStudio. Calculated fields or data blending do not have a GROUP BY-like function.
So, I found 2 alternative solutions:
create an additional table in my data with the first aggregation (sum over regions). This gives a table with the number of visitors for each date.
Then I import it in DataStudio and do the second aggregation in the table.
since my data is stored in BigQuery, a custom SQL query can be used to create another data source from the same dataset. This way, a GROUP BY statement can be used to sum over regions before the average is calculated.
These solutions have a big drawback that is, I cannot add controls to filter by region (since data from all regions is aggregated before entering datastudio).
The History:
I have a data set that refreshes every Monday morning adding last week's values to a growing tally until there is 52 weeks in the data set (9 separate cohorts), across 38 different departments.
I have built a power query to filter the department and compiled tables for each cohort, limiting the data to the last 17 weeks, and using excel forecast modelling then setup each table to forecast 16 weeks ahead.
Because the week beginning (WB) dates keep changing IO cant hard code the result table to cells within each cohort table.
My result table needs to show current month, month +1, month +2, and month +3 forecast values as per the highest date closest to or equal to EOM and I need this to be automated, hence a formula.
PS added complexity is that the table has date/value adjacent in (last 17 weeks) and columns separated in future 16 weeks of data in each table. Structure is exactly the same across all the 9 cohort forecast tables.
My Question:
Am I best to use a nested EOM formula, or VLOOKUP(MAX) based on the cohort_forecast_table image link below?
Because the current month needs to be current I have created a cell using =NOW().
I then complete a VLOOKUP within each cell in the master table that references the references the data in each sub-table usin MAX and EOMONTH for current month, then month+1, month+2, month+3, etc.
In a simplified broken down solution:
Date array = 'D3:D35'
Volume array = 'E3:E35'
End of current month formula cell B3: =MAX(($D$3:$D$35<EOMONTH(D1,0))*D3:D35)
Call for result in cell C3:
'=VLOOKUP(B3,Dates:Volumes,2,FALSE)'
I think this will work for me and thank you all...
I have a named set that returns the last 10 weeks from the current week. In the cube browser I get the value of a measure for each week.
I want to create another measure that contains the value of the previous week returned by the named set. Something like this :
Weeks Measure1 Measure2
Week 1 50 40
Week 2 35 50
Week 3 77 35
How to do this using MDX ?
Measure2 will be a tuple of whatever measure you want to show - lets calls it [Measures].[Revenue] and the currentmember of the hierarchy used in the Weeks column lagged by 1.
I don't know the structure of your cube so you'll need to adjust the following:
(
[Measures].[Revenue],
[Date].[Calendar Week of Year].CURRENTMEMBER.LAG(1)
)
My invoice report pull due dates depending on the selection of Payment Plan Code on UI (either semi, monthly, quarterly, annually, or even 18 installments.) It also accordingly pulls gross premium per due date. I need to pull this table per due date and the sum of the gross premium if they fall into one due date.
What I do is break and save the due dates into array. How can I group by them? Crystal doesn't seem to allow me to group by a shared value, or group by array.
You don't need array for this purpose.. using array complicates the report instead you can manipulate grouping like below:
Create a formula like below and use this formula to group.
if parameterselection = "monthly"
then Month(duedate)
else if parameterselection = "yearly"
then Year(duedate)
.
.
.
.
formula till end
Edit-------------------------------------------
In this case as per your comment you need to create one more group (Group2) with due date.
Now you have two groups group 1 is the one I wrote first and group2 using due date and this works
I use a DATE's master table for looking up dates and other values in order to control several events, intervals and calculations within my app. It has rows for every single day begining from 01/01/1990 to 12/31/2041.
One example of how I use this lookup table is:
A customer pawned an item on: JAN-31-2010
Customer returns on MAY-03-2010 to make an interest pymt to avoid forfeiting the item.
If he pays 1 months interest, the employee enters a "1" and the app looks-up the pawn
date (JAN-31-2010) in date master table and puts FEB-28-2010 in the applicable interest
pymt date. FEB-28 is returned because FEB-31's dont exist! If 2010 were a leap-year, it
would've returned FEB-29.
If customer pays 2 months, MAR-31-2010 is returned. 3 months, APR-30... If customer
pays more than 3 months or another period not covered by the date lookup table,
employee manually enters the applicable date.
Here's what the date lookup table looks like:
{ Copyright 1990:2010, Frank Computer, Inc. }
{ DBDATE=YMD4- (correctly sorted for faster lookup) }
CREATE TABLE datemast
(
dm_lookup DATE, {lookup col used for obtaining values below}
dm_workday CHAR(2), {NULL=Normal Working Date,}
{NW=National Holiday(Working Date),}
{NN=National Holiday(Non-Working Date),}
{NH=National Holiday(Half-Day Working Date),}
{CN=Company Proclamated(Non-Working Date),}
{CH=Company Proclamated(Half-Day Working Date)}
{several other columns omitted}
dm_description CHAR(30), {NULL, holiday description or any comments}
dm_day_num SMALLINT, {number of elapsed days since begining of year}
dm_days_left SMALLINT, (number of remaining days until end of year}
dm_plus1_mth DATE, {plus 1 month from lookup date}
dm_plus2_mth DATE, {plus 2 months from lookup date}
dm_plus3_mth DATE, {plus 3 months from lookup date}
dm_fy_begins DATE, {fiscal year begins on for lookup date}
dm_fy_ends DATE, {fiscal year ends on for lookup date}
dm_qtr_begins DATE, {quarter begins on for lookup date}
dm_qtr_ends DATE, {quarter ends on for lookup date}
dm_mth_begins DATE, {month begins on for lookup date}
dm_mth_ends DATE, {month ends on for lookup date}
dm_wk_begins DATE, {week begins on for lookup date}
dm_wk_ends DATE, {week ends on for lookup date}
{several other columns omitted}
)
IN "S:\PAWNSHOP.DBS\DATEMAST";
Is there a better way of doing this or is it a cool method?
This is a reasonable way of doing things. If you look into data warehousing, you'll find that those systems often use a similar system for the time fact table. Since there are less than 20K rows in the fifty-year span you're using, there isn't a huge amount of data.
There's an assumption that the storage gives better performance than doing the computations; that most certainly isn't clear cut since the computations are not that hard (though neither are they trivial) and any disk access is very slow in computational terms. However, the convenience of having the information in one table may be sufficient to warrant having to keep track of an appropriate method for each of the computed values stored in the table.
It depends on which database you are using. SQL Server has horrible support for temporal data and I almost always end up using a date fact table there. But databases like Oracle, Postgres and DB2 have really good support and it is typically more efficient to calculate dates on the fly for OLTP applications.
For instance, Oracle has a last_day() function to get the last day of a month and an add_months() function to, well, add months. Typically in Oracle I'll use a pipelined function that takes start and end dates and returns a nested table of dates.
The cool way of generating a rowset of dates in Oracle is to use the hierarchical query functionality, connect by. I have posted an example of this usage in another thread.
It gives a lot of flexibility without the PL/SQL overhead of a pipelined function.
OK, so I tested my app using 31 days/month to calculate interest rates & pawnshops are happy with it! Local Law prays as follows: From pawn or last int. pymt. date to 5 elapsed days, 5% interest on principal, 6 to 10 days = 10%, 11 to 15 days = 15%, and 16 days to 1 "month" = 20%.
So the interest table is now defined as follows:
NUMBER OF ELAPSED DAYS SINCE
PAWN DATE OR LAST INTEREST PYMT
FROM TO ACUMULATED
DAY DAY INTEREST
----- ---- ----------
0 5 5.00%
6 10 10.00%
11 15 15.00%
16 31 20.00%
32 36 25.00%
37 41 30.00%
42 46 35.00%
47 62 40.00%
[... until day 90 (forfeiture allowed)]
from day 91 to 999, daily prorate based on 20%/month.
Did something bad happen in the UK on MAR-13 or SEP-1752?