(Quicksight) Is it possible to have a claculated field that takes date field granularity into account - business-intelligence

Context: I have an dataset of Orders in quicksight, that is joined with Customer data. Because a Customer can have more than one Order the Customer data is duplicated and needs to be deduped.
I need to do an analysis of the number of days it took from the Customer to register (customer_date_added) to their first order (min(order_date_added)) and then bucket/group the results based on customer_date_added with different granularities of the date.
This is what I currently have working (6 visuals corresponding to the built-in date granularities in quicksight: year, quarter, month, week, day, hour)
*Visual 1* - x-axis:customer_date_added (aggregate year), y-axis:
ifelse(dateDiff(customer_date_added, min(order_date_added)) < 365, 1, 0)
*Visual 2* - x-axis:customer_date_added (aggregate quarter), y-axis:
ifelse(dateDiff(customer_date_added, min(order_date_added)) < 90, 1, 0)
*Visual 3* - x-axis:customer_date_added (aggregate month), y-axis:
ifelse(dateDiff(customer_date_added, min(order_date_added)) < 30, 1, 0)
*Visual 4* - x-axis:customer_date_added (aggregate week), y-axis:
ifelse(dateDiff(customer_date_added, min(order_date_added)) < 7, 1, 0)
.... etc
Issue: I have a lot of these dateDiff with bucketing visuals (not just days to first order) so my field list is getting overrun with fields like customer_first_order_within_year, customer_first_order_within_quarter, customer_first_order_within_month, etc. Also rather than just have one visual where I can change the date_granularity from year to month I have to maintain 6 different visuals for each dateDiff analysis I want to to.
What I want: One visual with two calculated fields (new_customer_with_first_order, new_customer_no_first_order). When I change the data granularity on customer_date_added to a new date granularity, the new_customer_with_first_order automatically displays customers that were added in that time period AND with a first order within that time period. Conversely new_customer_no_first_order would display customers that were added in that time period AND did not have an order within that time period. new_customer_with_first_order + new_customer_no_first_order = new customers within that time period.
What I have tried: I am relatively new to quicksight and business intelligence tools, but have a pretty good grasp of SQL. I have tried to read up on Level Aware Aggregation, Window Functions. None of these give examples using dates or date granularity. This seems like it would be a popular type of analysis but maybe it's not possible yet?
https://stackoverflow.com/a/63064505/3412268
https://docs.aws.amazon.com/quicksight/latest/user/windowMax-function.html
https://docs.aws.amazon.com/quicksight/latest/user/countOver-function.html
https://docs.aws.amazon.com/quicksight/latest/user/level-aware-aggregations.html

Related

Amazon Quicksight - Dynamic filter latest week by default

I think the question is fairly simple. I would like to have a dynamic filter on Quicksight. I have the column week which is a number (3, 4, 5 and 6) for example. The data is refreshed every week.
We want to show only the latest week by default (out of weeks 3, 4, 5 and 6, I want to filter by default on 6), but then the users can select if they want to see more weeks.
The week after, the default filter would be 7, and so on.
Is there a way to tell the filter to automatically filter by rule of MAX(week) or something like that?
It would be very helpful. I have other alternatives but they are not that great.
I would choose a date field that I understand that must exist in your data and then create a dynamic filter on that date field.
You create filters on date fields by selecting the filter conditions and date values that you want to use. There are three filter types for dates:
For your case, you will have to use
Relative – A series of date/time elements based on the current date. You can filter records based on the current date and your selected unit of measure (UOM). Date filter units include years, quarters, months, weeks, days, hours, and minutes.
Use the following procedure to create a relative filter for a date field.
On the toolbar at the left, choose Filter.
In the Filters pane that opens at left, choose the plus icon (+), and then choose a date field to filter on.
A new filter is added to the Filters pane.
In the Filters pane, choose the new filter to expand it.
For Filter type, choose Relative dates.
Choose a unit of time (week for your case).
Choose how you want the filter to relate to the time frame. For example, if you choose to report on weeks, your options are previous week, this week, week to date, last N weeks, and next N weeks.
If you choose Last n UOM, specify a number for your range—for example, last 2 weeks, or last 1 week.
Second solution.
Add Filter
Choose week
Type Top and Bottom Filter
Show Top write 1
By week ( use max aggregation)
Pasting an image from an analysis that I do the same thing for integer column year

Grouping then getting the sum of data in dynamic dated columns

I am currently working on a resource tracker for my company and I have each individuals capacity figure by week (weeks are in the columns and each person's information is in the row). I need to be able to sum all the time in a specific month for each job role to be able to report on.
I have currently thought about grouping the dates by selecting 4 weeks but due to my fields being dynamic and there being some 5 week months, it would not be able to accurately be able to report that months figures.
Unfortunately, you can't pivot the information due to the dates been in the columns rather than the rows.
I have yet to find any formula/code that can be used to get that information.
In the picture, I have added the information that I would like to be able to dynamically sum. The red outlines the month and the green outlines the job role information.
So I would like to be able to sum all that information under "July" and then the same for the other months so I can give my stakeholders a monthly figure of how many days capacity there is for each person/job role in that month.
=ARRAYFORMULA(QUERY({INDIRECT("Sheet1!B3:B"&COUNTA(Sheet1!B3:B)+2),
MMULT(QUERY(TRANSPOSE(QUERY(TRANSPOSE(Sheet1!E2:Z),
"where month(Col1)+1=7 and year(Col1)=2019", 0)),
"where Col1 is not null offset 1", 0), ROW(INDIRECT("A1:A"&COUNTA(
FILTER(Sheet1!A2:2, MONTH(Sheet1!A2:2)=7, YEAR(Sheet1!A2:2)=2019))))^0)},
"select Col1, sum(Col2) group by Col1 label sum(Col2)''", 0))

Cognos 11 Crosstab - need a value that doesn't have a reference to the column values

Crosstab report works 99%.
About 20 rows, all but one are ok.
5 columns - Company Division.
The rows are things like cost, revenue, revenue 2, etc.
All the rows that work have three attributes I'm using to select them:
Fiscal Year
Period
Solution.
The problem is there is table that lists an YTD rate for each period. This table is not Division Specific; it's company wide.
All the tables are linked to the accounting period table that has fiscal year and period. So the overall query limits data to fiscal year (?pFiscalYear?) and period <= ?pPeriod?, based on prompt page results.
The source table has this:
FY_CD PD_NO ACT_CURR_RT ACT_YTD_RT
2018 1 0.36121715 0.36121715
2018 2 0.32471476 0.34255512
2018 3 0.25240906 0.31210183
2018 4 0.33154745 0.31925874
Note the YTD rate is not an average of any of the other numbers.
When I select the ACT_YTD_RT, as a row, I want the ACT_YTD_RT that matches the selected period.
What I get is the average if I set the aggregation to average or the lowest if I set it to other aggregations. So sometimes, it looks right (if I run for period 1,2,3, as the rate kept falling), and sometimes it's wrong (period 4
returns .3121 instead of .3192).
I've tried a number of different methods and can generate garbage data (totals, min, max, average) and crossjoins but can't figure out how to get the value I'm looking for.
I want YTD_RT where fiscal year =?pFiscal? and period = ?pPeriod?.
I tried a straight if then clause:
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
but I get an error like this:
'ACT_YTD_RT' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. (SQLSTATE=42000, SQLERRORCODE=8120)
If I create another query that generates the right response and try to include it, I get a crossjoin error that the query I'm referencing is trying to crossjoin several other items in the crosstab query.
A union doesn't work (different number of columns).
Not sure how a join would work since the division doesn't exist in the rate table.
I maybe could create a view in the database that did a crossjoin of the division table and the rate table, add that to the framework and then I wouldn't have a crossjoin since the solution would be in the rate "table" (really view), but that seems wrong somehow.
If I could just write a freaking parameterized query direct to the database I'd be done. But in Cognos 11 crosstabs I can't find a place for a SQL query object. And that shouldn't be necessary.
I've spent hours and hours chasing this in circles.
Anybody have any ideas?
Thanks
Paul
So the earlier problem was that this:
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
Generated an error like this:
'ACT_YTD_RT' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. (SQLSTATE=42000, SQLERRORCODE=8120)
To fix the above, I had to add a cross join of the division table and the rate table as a view in the database. Then add that to the framework. Then build the data item this way:
total (
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
)
And now the "total" provides the missing group by. And the crossjoin in the database provides the division information so the crosstab is happy.
I still think there should have been an easier way to do this, but I have a functioning hammer at the moment.

Can I generate the number of business days in a month in Visual Studio?

I have a report that takes sales data from a few tables. I want to add a field that will divide the total sales for the given month by the total number of business days in that same month. Is there a way I can calculate that in an expression? Do I need to create a new table in the database specifically for months and their number of business days? How should I go about this?
Thank you
Intuitively, I would say that you need a simple function and a table.
The table is to host the exceptions like Independence day, labor day, etc.
The function will get two parameters: Month and Year (I'm not providing any sample code since you haven't specified which language you are using).
It will then build a date as yyyy-mm-01 (meaning, first day of the month). If will then loop from 2 to 31 and:
Create a new date by adding the index of the loop to the initial date,
Check if the resulting date is still within the month,
Check if it is a working or not working day (e.g. Sunday),
Check if it is found within the table of exceptions.
If the created date passes all the above tests, you add 1 to the counter.
Though it might look complex, it is not and it will provide you the correct answer regardless of the month (e.g. Feb.) and the year (leap or not).

Power BI (DAX): Calculating MoM Variance of a Measure Field

I have measure formula that takes a table and converts it to monthly count of distinct customers:
Active Publishers =
CALCULATE(
DISTINCTCOUNT( 'Net Revenue Data'[Publisher Name] ),
'Net Revenue Data'[Active Month] = 1)
Now, I would like to create a new formula that takes the Month-Over-Month (MoM) variance of this trend, like this:
This is the formula I attempted to get the net monthly change:
Net Change = 'Net Revenue Data'[Active Publishers] -
CALCULATE('Net Revenue Data'[Active Publishers],
PREVIOUSMONTH('Net Revenue Data'[Date (Month)]))
How can I create a measure that takes the monthly variance of the 'DistinctCountActiveMonths' measure?
I created an additional date table to relate to the revenue table's date column:
Date Table =
ADDCOLUMNS(CALENDAR("1/1/2000","12/31/2025"),"DateAsInteger",FORMAT([Date],"YYYYMDD"), "Year",YEAR([Date]), "MonthNumber",FORMAT([Date],"MM"),"YearMonthNumber",FORMAT([Date],"YYYY/MM"),"Ye arMonthShort",FORMAT([Date],"YYYY/mmm"),"MonthNameShort",FORMAT([Date],"mmm"),"MonthNameLong",FORMAT([Date],"mmmm"),"DayOfWeekNumber",WEEKDAY([Date]),"DayOfWeek",FORMAT([Date],"dddd"),"DayOfWeekShort",FORMAT([Date],"dddd"),"Quarter","Q"&FORMAT([Date],"Q"),"YearQuarter", FORMAT ( [Date], "YYYY" ) & "/Q" & FORMAT ( [Date], "Q" ))
Now I should be able to relate the two tables to create Month over Month variance.
PREVIOUSMONTH(), like all built-in time intelligence functions in DAX requires a proper date dimension with consecutive, non-repeating dates that span from January 1 of the first year you have data to December 31 of the last year you have data.
I am unsure, looking at the tags on your post whether you are using add-ins to Excel or the Power BI desktop program. If Excel, there is an option in the Power Pivot menu to 'Mark as date table', which you should always do in a Tabular model. If Power BI desktop, this functionality is not yet available, so you must create the relationship between your date dimension and fact table on the date field directly, and not on some surrogate key.
One solution to this problem requires 2 steps:
Create an intermediate calculated column that takes the last month's active publishers:
LM Active Pubs = CALCULATE([Active Pubs],DATEADD('Net Rev 09-14'[Date],-1,MONTH))
Subtract the current months "Active Pubs" from the last month's active publishers:
Change in Active Pubs = [Active Pubs]-[LM Active Pubs]

Resources