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" ) )
)
)
)
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] ) )
Please I want to update my client database based on the job type
id Job_type Meal_Ticket
---------------------------
1 x 20
2 2x 12
Meaning if I click on add 20 meal tickets on button click, it should update to this:
id Job_type Meal_Ticket
----------------------------
1 x 40
2 2x 52
I tried
UPDATE Staff
SET Rticket = CASE
WHEN Jobtype = 'x' THEN Rticket = SUM(Rticket + 20)
WHEN Jobtype = '2x' THEN Rticket = SUM(Rticket + 2*20)
ELSE Rticket
END
I think you want this:
UPDATE Staff
SET Rticket = CASE WHEN Jobtype = 'x' THEN Rticket + 20
WHEN Jobtype = '2x' THEN Rticket + 40 END
WHERE Jobtype IN ('x', '2x');
The only problem I see with your logic is that you are using SUM to add two quantities, when you should just be using the + operator.
i have below code i want to show date according to hours how to add 48 hours in my current date please help me in this i am new in angularjs.
"startjob_datetime" : ISODate("2017-03-13T14:21:12.231Z"),
var hours = 48 ;
var startdate = new Date(schedule_entry.startjob_datetime);
var enddate = new Date(schedule_entry.startjob_datetime).setHours(hours );
i want enddate = ISODate("2017-03-15T14:21:12.231Z"),
but its not working please check
and if normal working hours is 8 , than how to change date according to this, because 48 hours means two days, but if 8 hours normal duty time , it is almost 5 days
"startjob_datetime" : ISODate("2017-03-13T14:21:12.231Z"),
var hours = 48 * 60 * 60 * 1000 ; //Since 1hr = 60 mins, 1 min = 60 seconds, 1 second= 1000 milliseconds
var startdate = new Date(schedule_entry.startjob_datetime);
var enddate = new Date(schedule_entry.startjob_datetime).getTime() + hours ;
);
//This will give you endDate in milliseconds
//And replace 48 with whatever hours you want to add to the start date
My products have date_created and expires_in attributes. date_created is Magento date backend format while expires_in is a select that contains options as 1 week, 1 month etc.
Using those two attributes I'm trying to determine the total number of expired products. My idea was to write a query that selects:
products where date created + 1 week < now() AND expires_in = 1 week
AND
products where date created + 1 month < now() AND expires_in = 1 month
...
But I don't seem to be able to make even the first part of the first step to work:
$currentTimestamp = Mage::getModel('core/date')->timestamp(time());
$oneWeekTimestamp = Mage::getModel('core/date')->timestamp(strtotime("+1 week"));
$products = Mage::getResourceModel('catalog/product_collection')
->setStoreId(Mage::app()->getStore()->getId())
->addAttributeToSelect('')
...
//these are what i have tried so far:
$products->addAttributeToFilter('date_updated + ' . $oneWeekTimestamp , array('gt' => $currentTimestamp));
$products->addAttributeToFilter(new Zend_Db_Expr('date_updated + ' . $oneWeekTimestamp), array('gt' => $currentTimestamp));
$products->addAttributeToFilter("DATEDIFF($currentTimestamp, 'date_updated')" , array('gt' => 7));
$countExpired = $products -> count();
None of them seem to work. If possible I'd like the cross RDBMS solution.
You can do this in following way:
$currentTimestamp = Mage::getModel('core/date')->timestamp(time());
$oneWeekTimestamp = Mage::getModel('core/date')->timestamp(strtotime("+1 week"));
$oneweekDate=date("Y-m-d H:i:s",$oneWeekTimestamp);
$products->addAttributeToFilter('date_updated',array('date'=>true,'gt',$oneweekDate);