Power BI - Value increases 3 days or more in a row - formatting

Hi I am wanting to have a RAG trigger for if a value has increased 3 days in a row or 5 days in a row.
For example if the value increases 3 days in a row.
26/07 1
27/07 5
28/07 12
I would want the value colour to turn amber
and if it increases 5 days or more in a row I would want the colour to be red.
Is this possible?
Thanks

This is probably not the nicest solution but that is a start.
At first, you will need to create a measure to return the colour based on your condition. Something like that:
Measure =
VAR PreviousDayValue =
CALCULATE (
MIN ( Dataset[Value] ),
DATEADD ( Dataset[Date], -1, DAY )
)
VAR TwoDaysAgoValue =
CALCULATE (
MIN ( Dataset[Value] ),
DATEADD ( Dataset[Date], -2, DAY )
)
VAR ThreeDaysAgoValue =
CALCULATE (
MIN ( Dataset[Value] ),
DATEADD ( Dataset[Date], -3, DAY )
)
VAR FourDaysAgoValue =
CALCULATE (
MIN ( Dataset[Value] ),
DATEADD ( Dataset[Date], -4, DAY )
)
RETURN
IF (
MIN ( Dataset[Value] ) > PreviousDayValue
&& PreviousDayValue > TwoDaysAgoValue
&& TwoDaysAgoValue > ThreeDaysAgoValue
&& ThreeDaysAgoValue > FourDaysAgoValue,
2,
IF (
MIN ( Dataset[Value] ) > PreviousDayValue
&& PreviousDayValue > TwoDaysAgoValue
&& TwoDaysAgoValue > ThreeDaysAgoValue,
1,
BLANK ()
)
)
And then you can setup conditional formatting for your [Value] column using "Format by rules" option:
After that, it will look like that:
The fourth row was also formatted as red here, but you can change it to amber simply switching conditions in the measure formula.

Related

Querying the same column for 3 different values

I'm trying hard to extract the data in the format I need, but unsuccessful til now.
I have the following table
id_ticket, date_ticket, office_ticket, status_ticket
I need the query to return me, for EVERY MONTH, and always for the same OFFICE:
the number of tickets (COUNT) with any status
the number of tickets (COUNT) with status = 5
the number of tickets (COUNT) with status = 6
Month
Year
The query I made to return ONLY the total amount of tickets with any status was this. It worked!
SELECT
COUNT (id_ticket) as TotalTicketsPerMonth,
'sYear' = YEAR (date_ticket),
'sMonth' = MONTH (date_ticket)
FROM crm_vw_Tickets
WHERE office_ticket = 1
GROUP BY
YEAR (date_ticket), MONTH (date_ticket)
ORDER BY sYear ASC, sMonth ASC
Returning the total amount of ticket with status=5
SELECT
COUNT (id_ticket) as TotalTicketsPerMonth,
'sYear' = YEAR (date_ticket),
'sMonth' = MONTH (date_ticket)
FROM crm_vw_Tickets
WHERE office_ticket = 1 AND status_ticket = 5
GROUP BY
YEAR (date_ticket), MONTH (date_ticket)
ORDER BY sYear ASC, sMonth ASC
But I need the return to be something like:
Year Month Total Status5 Status6
2018 1 15 5 3
2018 2 14 4 5
2018 3 19 2 8
Thank you for your help.
You are close. You can use a CASE Expression to get what you need:
SELECT
COUNT (id_ticket) as TotalTicketsPerMonth,
SUM(CASE WHEN status_ticket = 5 THEN 1 END) as Status5,
SUM(CASE WHEN status_ticket = 6 THEN 1 END) as Status6,
'sYear' = YEAR (date_ticket),
'sMonth' = MONTH (date_ticket)
FROM crm_vw_Tickets
WHERE office_ticket = 1
GROUP BY YEAR (date_ticket), MONTH (date_ticket)
ORDER BY sYear ASC, sMonth ASC
The following code builds off JNevill's answer to include summary rows for "missing" months, i.e. those with no tickets, as well as months with tickets. The basic idea is to create a table of all of the months from the first to the last ticket, outer join the ticket data with the months and then summarize the data. (Tally table, numbers table and calendar table are more or less applicable terms.)
It is a Common Table Expression (CTE) that contains several queries that work step-by-step toward the result. You can see the results of the intermediate steps by replacing the final select statement with one of the ones commented out above it.
-- Sample data.
declare #crm_vw_Tickets as Table ( id_ticket Int Identity, date_ticket Date, office_ticket Int, status_ticket Int );
insert into #crm_vw_Tickets ( date_ticket, office_ticket, status_ticket ) values
( '20190305', 1, 6 ), -- Shrove Tuesday.
( '20190501', 1, 5 ), -- May Day.
( '20190525', 1, 5 ); -- Towel Day.
select * from #crm_vw_Tickets;
-- Summarize the data.
with
-- Get the minimum and maximum ticket dates for office_ticket 1.
Limits as (
select Min( date_ticket ) as MinDateTicket, Max( date_ticket ) as MaxDateTicket
from #crm_vw_Tickets
where office_ticket = 1 ),
-- 0 to 9.
Ten ( Number ) as ( select * from ( values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9) ) as Digits( Number ) ),
-- 100 rows.
TenUp2 ( Number ) as ( select 42 from Ten as L cross join Ten as R ),
-- 10000 rows. We'll assume that 10,000 months should cover the reporting range.
TenUp4 ( Number ) as ( select 42 from TenUp2 as L cross join TenUp2 as R ),
-- 1 to the number of months to summarize.
Numbers ( Number ) as ( select top ( select DateDiff( month, MinDateTicket, MaxDateTicket ) + 1 from Limits ) Row_Number() over ( order by ( select NULL ) ) from TenUp4 ),
-- Starting date of each month to summarize.
Months as (
select DateAdd( month, N.Number - 1, DateAdd( day, 1 - Day( L.MinDateTicket ), L.MinDateTicket ) ) as StartOfMonth
from Limits as L cross join
Numbers as N ),
-- All tickets assigned to the appropriate month and a row with NULL ticket data
-- for each month without tickets.
MonthsAndTickets as (
select M.StartOfMonth, T.*
from Months as M left outer join
#crm_vw_Tickets as T on M.StartOfMonth <= T.date_ticket and T.date_ticket < DateAdd( month, 1, M.StartOfMonth ) )
-- Use one of the following select statements to see the intermediate or final results:
--select * from Limits;
--select * from Ten;
--select * from TenUp2;
--select * from TenUp4;
--select * from Numbers;
--select * from Months;
--select * from MonthsAndTickets;
select Year( StartOfMonth ) as SummaryYear, Month( StartOfMonth ) as SummaryMonth,
Count( id_ticket ) as TotalTickets,
Coalesce( Sum( case when status_ticket = 5 then 1 end ), 0 ) as Status5Tickets,
Coalesce( Sum( case when status_ticket = 6 then 1 end ), 0 ) as Status6Tickets
from MonthsAndTickets
where office_ticket = 1 or office_ticket is NULL -- Handle months with no tickets.
group by StartOfMonth
order by StartOfMonth;
Note that the final select uses Count( id_ticket ), Coalesce and an explicit check for NULL to produce appropriate output values (0) for months with no tickets.

Getting error when Calculating the Sum of premium values using DAX on a slowly changing dimension

Using DAX - I need to calculate the total premium amount for policies with a certain status - using a slowly changing dimension as a source.
This is something that's running within SSAS tabular model.
The solution has two tables - dim_date (which is a calendar table) and a Dim_contract (which have all my policies listed)
The Dim_Contract table is a slowly changing dimension.
The table format:
DW_ContractID DW_EffectiveFromDate contract_number actual_recurring_collection ContractStatusTLA
-2145825896 22 August 2018 4303140 80 PIN
-2145627139 26 September 2018 4303140 80 INF
-2145428382 09 October 2018 4303140 80 Can
-2145229625 21 August 2018 4303142 100 PIN
-2145030868 22 September 2018 4303142 100 NTU
-2144832111 02 September 2018 4303999 50 PIN
-2144633354 03 September 2018 4303999 50 INF
I've done a calculation to count the policies - which work 100%.
With this calc, we count the number of policies for each time period. (depending what the user selects)
Example - if we want to count the number of policies as at the end of September per status we should get:
INF: 2 (This is counting policy numbers 4303140 and 4303999 as their last status is INF)
CAN: 0
NTU: 1
The code used to do the counts:
PolicyCount_NTU :=
IF (
MIN ( DIM_Date[Date] )
>= CALCULATE ( MIN ( DIM_Contract[DW_EffectiveFromDate] ), ALL ( DIM_Contract ) ),
IF (
MIN ( DIM_Date[Date] )
<= CALCULATE ( MAX ( DIM_Contract[DW_EffectiveFromDate] ), ALL ( DIM_Contract ) ),
CALCULATE (
COUNTROWS (
FILTER (
DIM_Contract,
DIM_Contract[DW_ContractID]
= CALCULATE (
MAX ( DIM_Contract[DW_ContractID] ),
ALL ( DIM_Contract ),
DIM_Contract[contract_number] = EARLIER ( DIM_Contract[contract_number] ),
( DIM_Contract[DW_EffectiveFromDate] ) <= VALUES ( DIM_Date[Date] )
)
)
),
LASTDATE ( DIM_Date[Date] ),
DIM_Contract[ContractStatusTLA] = "NTU"
)
)
)
The problem comes in with the calc to get the sum of the amounts...
I used this code:
PolicyAPI_NTU :=
IF (
MIN ( DIM_Date[Date] )
>= CALCULATE ( MIN ( DIM_Contract[DW_EffectiveFromDate] ), ALL ( DIM_Contract ) ),
IF (
MIN ( DIM_Date[Date] )
<= CALCULATE ( MAX ( DIM_Contract[DW_EffectiveFromDate] ), ALL ( DIM_Contract ) ),
CALCULATE (
SUM ( DIM_Contract[actual_recurring_collection] ),
(
FILTER (
DIM_Contract,
DIM_Contract[DW_ContractID]
= CALCULATE (
MAX ( DIM_Contract[DW_ContractID] ),
ALL ( DIM_Contract ),
DIM_Contract[contract_number] = EARLIER ( DIM_Contract[contract_number] ),
DIM_Contract[DW_EffectiveFromDate] < VALUES ( DIM_Date[Date] )
)
)
),
LASTDATE ( DIM_Date[Date] ),
DIM_Contract[ContractStatusTLA] = "NTU"
)
)
)
Using the last piece of code to get the SUM of the amounts doesn't work - I get an error: Error: Calculation error in measure 'DIM_Contract'[PolicyAPI_NTU]: A table of multiple values was supplied where a single value was expected.
I suspect your problem is here
DIM_Contract[DW_EffectiveFromDate] < VALUES ( DIM_Date[Date] )
The DAX doesn't know how to do a comparison if DIM_Date[Date] has multiple values.
Try using a MAX or MIN or LASTDATE or something similar instead of VALUES.

Dax Measure - Value table compare value

I have a table FactSales
And tried but didn’t get ant satisfactory result.
Id like to calculate old results and compare to my actual one and see how many customers whose bought product B before (before 90 days) didn’t buy the same product in last 3 months according to the date filter
I tried this:
Customers inactive =
VAR Daysbefore90: Max(DimDate[date]) -90
> RETURN CALCULATE( DISTINCTCOUNT(FSales[CustomerKey]); DimProduct[Product] = “A”; FILTER( ALL ( DimDate[Date] );
DimDate[Date] < DaysBefore90 ); NOT(CONTAINS( FILTER(FSales;
RELATED(DimDate[Date]) >= Daysbefore90 && DimDate[Date]) <=
MAX(Daysbefore90): RELATED(DimProduct[Product]) = “A”) ;
FSales[CustomerKey]; FSales[CustomerKey] ) ) )
This will get you all customer who purchased item 'B' in the last 90 Days:
Customers Who Bought Product B 90 Days Ago :=
CALCULATE (
DISTINCTCOUNT ( 'FSale'[CustomerKey] ),
ALL ( 'DimDate'[Date] ),
KEEPFILTERS (
DATESINPERIOD ( 'DimDate'[Date], MAX ( 'DimDate'[Date] ), -90, DAY )
),
KEEPFILTERS ( DimProduct[Product] = "B" )
)
Your question is a little hard to read, so maybe update it and we can go from there.

DAX Measure - Summing up values between start-end dates in the same table

I have an "Assignments" Table like this:
Date End Date Allocation1111 Alex AA 11/20/2016 12/30/2016 0.52222 Eric BB 10/20/2016 11/30/2016 0.43333 John CC 10/20/2016 12/30/2016 12222 Eric DD 11/20/2016 1/1/2017 0.5
I also have a simple "Date" Table which DOES NOT have a relationship with the Assignments Table like this:
Date Month Month_Text Year Month-Year10/1/2016 10 Oct 2016 Oct-1610/2/2016 10 Oct 2016 Oct-1610/3/2016 10 Oct 2016 Oct-1610/4/2016 10 Oct 2016 Oct-16
Than I have the following DAX measure:
==============================
Sum of Assignments :=CALCULATE ( SUMX ( Assignments_Tbl, Assignments_Tbl[Allocation] ), FILTER ( VALUES ( Date_Tbl ), Date_Tbl[Date] >= MINX ( Assignments_Tbl, Assignments_Tbl[Start Date] ) && Date_Tbl[Date] <= MAXX ( Assignments_Tbl, Assignments_Tbl[End Date] ) )) * CALCULATE ( DISTINCTCOUNT ( Date_Tbl[Month] ), FILTER ( VALUES ( Date_Tbl ), Date_Tbl[Date] >= MINX ( Assignments_Tbl, Assignments_Tbl[Start Date] ) && Date_Tbl[Date] <= MAXX ( Assignments_Tbl, Assignments_Tbl[End Date] ) ) )
==============================
All seems OK when I have the Start Date and End Date as part of my Pivot Table like below:
Sum of Assignments in a pivot table with Start/End Dates
HOWEVER, if I remove the Start Date and End Date from the pivot table, the measure is calculating incorrectly and I can't find why.
For instance, as the pic below, the red circles show 0.9 for a person name "Eric" in in Oct-2016, instead of 0.4.
Sum of Assignments measure calculating incorrectly
I tried many things, but got stuck on this measure. Any idea?
After some deeper investigation, here is the proper measure:
New Measure =
SUMX (
Assignments_Tbl,
CALCULATE (
SUM ( Assignments_Tbl[Allocation] ) * DISTINCTCOUNT ( Date_Tbl[Month-Year] ),
FILTER (
VALUES ( Date_Tbl ),
Date_Tbl[Date] >= EARLIER ( Assignments_Tbl[Start Date], 1 )
&& Date_Tbl[Date] <= EARLIER ( Assignments_Tbl[End Date], 1 )
)
)
)

How to avoid DIVIDE BY ZERO error in an SQL query

SELECT YEAR, period, round((1- sum(rej_qty) / sum(recd_qty))*100, 0)
FROM TAB_A
WHERE sid = '200'
AND sdid IN ('4750')
AND
(
(
YEAR ='2011'
AND period IN('01_JAN')
)
OR
(
YEAR = '2010'
AND period IN('02_FEB','03_MAR','04_APR','05_MAY','06_JUN','07_JUL','08_AUG','09_SEP','10_OCT','11_NOV','12_DEC')
)
)
group by year, period
For a particular month, recd_qty is ZERO because of which I am getting DIVIDE BY ZERO error.
Is there any way to avoid DIVIDE BY ZERO error?
I there any way where in that particular month is ignored?
Have you tried using NULLIF()?
SELECT
( 100 / NULLIF( 0, 0 ) ) AS value
;
Oracle Doc
http://www.oracle-base.com/articles/9i/ANSIISOSQLSupport.php#NULLIFFunction
Another example
http://www.bennadel.com/blog/984-Using-NULLIF-To-Prevent-Divide-By-Zero-Errors-In-SQL.htm
If you want to ignore such records you can use a subquery
SELECT YEAR, period, round((1- rej_sum / recd_sum)*100, 0) FROM
(
SELECT YEAR, sum(rej_qty) rej_sum, sum(recd_qty) recd_sum
FROM TAB_A
WHERE sid = '200'
AND sdid IN ('4750')
AND
(
(
YEAR ='2011'
AND period IN('01_JAN')
)
OR
(
YEAR = '2010'
AND period IN ('02_FEB','03_MAR','04_APR','05_MAY','06_JUN','07_JUL','08_AUG','09_SEP','10_OCT','11_NOV','12_DEC')
)
)
group by year, period
)
WHERE recd_sum <> 0;
If you want to keep them and handle the division by zero issue, you can use decode or case
SELECT YEAR, period, DECODE(recd_qty, 0, NULL, round((1- sum(rej_qty) / sum(recd_qty))*100, 0))
round(ISNULL(
((1- sum(rej_qty)) / NULLIF( (sum(recd_qty))*100), 0 )),
0
),0)
If you replace your division using NULLIF to set a NULL when there is divide by zero, then an ISNULL to replace the NULL with a 0 - or indeed whatever value you want it to.
CASE WHEN sum(recd_qty) <> 0 THEN round((1- sum(rej_qty) / sum(recd_qty))*100, 0) ELSE 0 END