Measure does not work for Month Threshold - sql-server

I build this Dax measure
_Access_Daily = CALCULATE(
DISTINCTCOUNTNOBLANK(ApplicationAccessLog[ApplicationUserID]),
FILTER('Date','Date'[DateId]=SELECTEDVALUE('DateSelector'[DateId],MAX('DateSelector'[DateId]))))+0
_Access__PreviousDay = CALCULATE(
DISTINCTCOUNTNOBLANK(ApplicationAccessLog[ApplicationUserID]), FILTER('Date','Date'[DateId]=SELECTEDVALUE('DateSelector'[DateId],MAX('DateSelector'[DateId]))-1 ))+0
The Date Selector table is a disconnected table containing dates from the 20th Jan to now. Dateid is a whole number like 20200131.
The Date table is a standard date table with all the dates between 1970 and 2038. Date id is a whole number like 20200131.
However it does not seems to work for the month threshold between Jan and Feb ? So if selected date is 01/02/2020 then it does not return correctly for the 31/01/2020.

As mentioned in the comments, the root problem here is that the whole numbers you use are not dates. As a result, when you subtract 1 and cross month (or year) boundaries, there is no calendar intelligence that can adjust the numbers properly.
Your solution (using 'Date'[DayDateNext]) might work, and if for some additional considerations this design is a must, go with it. However, I'd suggest to revisit the overall approach and use real dates instead of "DateId". You will then be able to use built-in DAX time intelligence, and your code will be more elegant and faster.
For example, if your "Date" and "DateSelector" tables have regular date fields, your code can be re-written as follows:
_Access_Daily =
VAR Selected_Date = SELECTEDVALUE ( 'DateSelector'[Date], MAX ( 'DateSelector'[Date] ) )
VAR Result =
CALCULATE (
DISTINCTCOUNTNOBLANK ( ApplicationAccessLog[ApplicationUserID] ),
'Date'[Date] = Selected_Date
)
RETURN
Result + 0
and:
_Access_PreviousDay =
CALCULATE ( [_Access_Daily], PREVIOUSDAY ( 'Date'[Date] ) )

Related

DAX average not in date period

What would the equivalent DAX be for this SQL?
SELECT AVG(CountRows) FROM pbi.FactVend AS FV JOIN pbi.DimAsset AS DA ON DA.KEY_Asset = FV.KEY_Asset WHERE CAST(FV.KEY_VendDate AS Date) NOT BETWEEN DA.ExcludedFromDate AND DA.ExcludedToDate
I have two tables, Vend and Asset. I want to exclude the rows from Vend where the VendDate is in an excluded period. Something like below however I can't get the DAX right. If i filter Vend it cannot see the Asset columns also doesn't seem to like being supplied convert date, KEY_VendDate is Int YYYYMMDD...
Average Cup Vends =
CALCULATE(AVERAGE(Vend[CountRows]),
FILTER(Vend, NOT(DATESBETWEEN(CONVERT(Vend[KEY_VendDate], DATETIME), Asset[Excluded From Date], Asset[Excluded To Date])))
Things I don't understand but I assume:
Assets[ProductKey] has unique values.
Vends (which from now on I'll call Transactions) contains one column
related to Assets[ProductKey]
Transactions[Date] is a Date/Time column
Transactions is related to a Dates Table, which is not related to
Assets.
I don't know how you're trying to use the measurement, but I hope the following example can help you find the right path.
I excluded Assets[ProductKey] only on January, as you can see in the assets table image, ie:
Assets[ProductKey]=21 was excluded from 1/21/2021 00:00 to 1/22/2021
00:00,
Assets[ProductKey]=22 was excluded from 1/22/2021 00:00 to
1/23/2021 00:00 and so on
You can access the columns in the expanded Transactions table through RELATED.
FILTER(Transactions,
NOT(AND(
Transactions[TransactionDate]>=RELATED(Assets[ExcludedFromDate]),
Transactions[TransactionDate]<RELATED(Assets[ExcludedToDate]))))
In my example. I used this:
AVGNonExcludedTransactions :=
VAR SMZDateContext=SUMMARIZE(CalendarDateTime,CalendarDateTime[Year],CalendarDateTime[MonthName])
VAR NonExcludedTransactions=
FILTER(Transactions,
NOT(AND(
Transactions[TransactionDate]>=RELATED(Assets[ExcludedFromDate]),
Transactions[TransactionDate]<RELATED(Assets[ExcludedToDate]))))
VAR Result=
ADDCOLUMNS(SMZDateContext, "Count", CALCULATE(COUNTROWS(INTERSECT(
Transactions, NonExcludedTransactions))))
RETURN
AVERAGEX(Result,[Count])
... removing the highlighted rows. One day of exclusion for each [ProductKey] in the Assets table and more than one day of exclusion for each product in the Transactions table.
which can be analyzed by changing INTERSECT() to EXCEPT() and increasing granularity at the day level.
EDIT:
In this second part the objective is not to use FILTER on the Transactions table. However, I think the following approach can be improved by changing dates to numbers. And I still don't know if it's more efficient than using FILTER on a 10M row table. Probably not, because it would be necessary to have less than 100 products and more than 2M transactions
This is what the model looks like:
This time TCountR is a simpler measure:
TCountR = COUNTROWS(Transactions)
And the filter is calculated in another way. With a single DateTime column containing the exclusion period for each product within the granularity of CalendarDateTime:
AVGTCountRNonExcluded :=
VAR TotalRow =
SUMMARIZE(CalendarDateTime,CalendarDateTime[Year],CalendarDateTime[MonthName])
VAR AllCJ =
CROSSJOIN(SUMMARIZE(Products,Products[ProductKey]),SUMMARIZE(CalendarDateTime,CalendarDateTime[DateTime]))
VAR Excluded=
SELECTCOLUMNS(
GENERATE(Assets,
ADDCOLUMNS(
CROSSJOIN (
//Dates in Transactions should be rounded down at the hour level.
// -1 means that the day 1/2/2021 is not included
//From 1/1/2021 00:00 to 1/1/2021 23:00
////
//Without adding or subtracting a value:
//From 1/1/2021 00:00 to 1/2/2021 23:00
CALENDAR(Assets[ExcludedFromDate],Assets[ExcludedToDate]-1),
SELECTCOLUMNS(GENERATESERIES(0,23,1),"Time",TIME([Value],0,0))),
"DateTime", [Date] + [Time])),
"ProductKey", Assets[ProductKey], "DateTime", [DateTime])
VAR FilteredOut=EXCEPT(AllCJ,Excluded)
VAR Result = ADDCOLUMNS(TotalRow,"Count", CALCULATE([TCountR],KEEPFILTERS(FilteredOut)))
RETURN
AVERAGEX(Result,[Count])
The result is the same.
EDIT 2
Why not?
If you already understood the 2nd approach, you may wonder, what if I can add a column to my Transactions table and change the [TransactionDate] format from DateTime to Date, and use a Dates Table only at the Date level.
Example:
1/1/2021 23:00 To 1/1/2021 00:00
1/2/2021 00:00 To 1/2/2021 00:00
The code gets simpler:
AVGCountRowsDateLevel :=
VAR TotalRow= SUMMARIZE(Dates,Dates[Year],Dates[MonthName])
VAR AllCJ=CROSSJOIN(SUMMARIZE(Products,Products[ProductKey]),SUMMARIZE(Dates,Dates[Date]))
VAR Excluded=
SELECTCOLUMNS(
GENERATE(Assets,
DATESBETWEEN(Dates[Date],Assets[ExcludedFromDate],Assets[ExcludedToDate]-1)),
"ProductKey", Assets[ProductKey], "Date", [Date])
VAR FilteredOut=EXCEPT(AllCJ,Excluded)
VAR Result = ADDCOLUMNS(TotalRow,"Count", CALCULATE([TCountR],KEEPFILTERS(FilteredOut)))
RETURN
AVERAGEX(Result,[Count])
And the result is the same
As I said at the beginning, this is an example, which I hope can help you find the solution.
Assuming you have a relationship from Assets[KEY_Asset] to Vend[KEY_Asset] and Vend[VendDate] is formatted as a date, then you can write
Average Cup Vends =
CALCULATE (
AVERAGE ( Vend[CountRows] ),
FILTER (
Vend,
NOT AND (
Vend[VendDate] > RELATED ( Asset[Excluded From Date] ),
Vend[VendDate] < RELATED ( Asset[Excluded To Date] )
)
)
)
This requires first defining a calculated column Vend[VendDate] to convert Vend[KEY_VendDate] from YYYYMMDD to a date format. You can define such a column as follows:
VendDate =
DATE (
LEFT ( Vend[KEY_VendDate], 4 ),
MID ( Vend[KEY_VendDate], 5, 2 ),
RIGHT ( Vend[KEY_VendDate], 2 )
)
Another option is to convert the Asset date columns into integer format instead.
Average Cup Vends =
CALCULATE (
AVERAGE ( Vend[Countrows] ),
FILTER (
Vend,
NOT AND (
Vend[KEY_VendDate]
> VALUE ( FORMAT ( RELATED ( Asset[Excluded From Date] ), "yyyymmdd" ) ),
Vend[KEY_VendDate]
< VALUE ( FORMAT ( RELATED ( Asset[Excluded To Date] ), "yyyymmdd" ) )
)
)
)

POWER BI - workaround possible for recursive calculation of my dax measure?

I have 2 tables on orders with the order validity date and in transit stock (stock reaching where the order will be serviced).
(using sample data to simplify for understanding)
I am looking for a final calculation like this in my final table -
have done the calculation till column 4 in power BI
if this was in excel i could have simply done
used_stock(2) = serviced(1) + used_stock(1)
avail_stock(2) = total_qty(2) - used_stock(2)
serviced(2) = min(order(2),avail_stock(2))
My base tables look like this - 
order table -
intransit table -
I have done the total_qty measure calculation by finding the cumulative sum of shipment quantity for the dates before selected value of order validity date.
I am trying to do the rest of the measures but ending up in circular references. Is there a way I can do it?
edit -
Clarifying it a bit more for the logic needed -
let's say the 2nd order is 15 and the 2nd shipment reaches on 24th, then the base data and output table should look like this -
With present proposed solution the table will erroneously look like -
Try with these below measures-
total_qty =
VAR current_row_date = MIN('order'[order valid till date])
RETURN
CALCULATE(
SUM(intrasit[quantity in shipment]),
FILTER(
ALL(intrasit),
intrasit[expected date of reaching] < current_row_date
)
)
used_stock =
VAR current_row_date = MIN('order'[order valid till date])
RETURN
CALCULATE(
SUM('order'[order quantity]),
FILTER(
ALL('order'),
'order'[order valid till date] < current_row_date
)
) + 0
avail_stock = [total_qty] - [used_stock]
serviced =
IF(
MIN('order'[order quantity]) <= [avail_stock],
MIN('order'[order quantity]),
[avail_stock]
)
Here is your final output-

Removing Blank Days from Power BI Chart

I have created a weekly request measure like so :
RequestsWeekly = var result= CALCULATE(
DISTINCTCOUNTNOBLANK(SessionRequests[RequestDateTime]),
FILTER('Date','Date'[WeekDate]=SELECTEDVALUE('DateSelector'[WeekDate],MAX('DateSelector'[WeekDate]))))+0
RETURN
IF ( NOT ISBLANK ( result ), result)
DateSelector is a standalone table (not connected to any other table in data model) that I have created for all the dates for a dropdown menu select for a Power BI Dasbboard. Unfortunately as there are less dates in the Date Selector table than the Date table, I get ...
Date table is the standard DATE table full of dates from 1970 to 2038. Date connects to Session Requests via a many to one relationships, single way filter. Session Requests is the main fact table.
I need to get rid of the blank row in my result set via DAX so it does not appear in my chart on the X axis. I have tried lots of different DAX combos like blank () and NOT ISBLANK. Do I need to create a table for the result set and then try to filter out the blank day there?
You should not check if the result is empty but if the VALUE ( Table[DayNameShort] ) exists for your current row context:
RequestsWeekly =
VAR result =
CALCULATE (
DISTINCTCOUNTNOBLANK ( SessionRequests[RequestDateTime] ),
FILTER (
'Date',
'Date'[WeekDate]
= SELECTEDVALUE (
'DateSelector'[WeekDate],
MAX ( 'DateSelector'[WeekDate] )
)
)
) + 0
RETURN
IF (
NOT ISBLANK (
VALUE ( Table[DayNameShort] ) -- put here correct table name
),
result
)

Netezza date function for current date - 16 days

I want to pull today's date plus the last four weeks. Does anyone know a function for this in Netezza? What I have below is a guess that doesn't work. Also, I don't want to extract the date.
Select c.BUSINESS_UNIT_NBR, c.BUSINESS_UNIT_NAME, b.STORE_NBR, b.INV_CUST_ACNT_NBR,c.INV_CUST_NAME, a.NDC_NBR, a.GENERIC_NAME, a.INV_NBR, a.CONTRACT_ID, a.CONTRACT_NAME, a.ORD_DT, b.INV_DT, b.SHIP_DT, a.ORD_QTY, a.SHIPPED_QTY, a.INV_PRICE_AMT, a.INV_COST_AMT, a.MARKUP_MARKDOWN_PCT, a.INV_LINE_AMT
from fct_dly_invoice_detail a, fct_dly_invoice_header b, dim_invoice_customer c
where a.INV_HDR_SK = b.INV_HDR_SK
and b.DIM_INV_CUST_SK = c.DIM_INV_CUST_SK
and a.SRC_SYS_CD = 'ABC'
and a.NDC_NBR is not null
**and b.inv_dt(current_date)-16**
and b.store_nbr in (813, 1197, 2771, 3048, 3177, 3387, 3477, 3602, 3766, 3912, 4020, 4138, 4228, 4434, 4435, 4507, 4742, 4791, 5353, 5392, 5775, 5776, 5890, 6177, 6692, 6736, 6806, 7933, 9175, 9472)
Assuming inv_dt is the column you want to filter on, your where predicate should include:
WHERE
...
inv_dt between CURRENT_DATE - 16 and CURRENT_DATE
...
16 days does not equal four weeks, but adjust that number accordingly to your needs.

find the Day of week of a particular date

i have an object which has 2 dates startdate_c and enddate_c .
i need to find a way to find the days of week these dates fall in
For example
startdate = 1 jun 2012 and enddate = 3 jun2012
I need to know which days of the week the days between these dates fall in.
In this example
Mon = false, tue = false, wed = false, thu=false, fri=true,sat=true,sun=true
I want to use this in a Vf page to render the somefields based on the boolean value.
Any pointers would be of great help.
Date has a method called toStartOfWeek which you could leverage, assuming your two dates do lie within the same week you could simply do something like this:
date weekStart = startdate.toStartOfWeek();
list<boolean> days = new list<boolean>();
for(integer i = 0; i < 7; i++)
{
days.add(weekStart.addDays(i) >= startdate && weekStart.addDays(i) <= enddate);
}
A little bit crude, but it'll give you an array of 7 boolean values. For longer/unknown ranges you could use a date cursor and increment that instead of an integer here, but this should get you started. Note, I've not tested this code ;)

Resources