I have two date fields with times. I want to calculate the response time of mins between Start and Finish excluding lunch breaks, weekends, and holidays.
I found the formula to exclude weekends, and holidays but how to exclude lunch also
Working hour start 9:00
End: 17:30
Response time (SLA) =
VAR _M =
CALCULATE (
COUNTROWS ( 'Date' ),
DATESBETWEEN ( 'Date'[Date], 'Table'[StartDate] + 1, 'Table'[ClosedDate] - 1 ),
'Date'[Weekday1] <> 6
&& 'Date'[Weekday1] <> 7,
ALL ( 'Table' )
) * 7.5 * 60
VAR _S =
IF (
WEEKDAY ( 'Table'[StartDate], 2 ) IN { 6, 7 },
0,
IF (
HOUR ( 'Table'[StartDate] ) < 9,
7.5 * 60,
DATEDIFF (
'Table'[StartDate],
DATE ( YEAR ( 'Table'[StartDate] ), MONTH ( 'Table'[StartDate] ), DAY ( 'Table'[StartDate] ) )
+ TIME ( 17, 00, 00 ),
MINUTE
)
)
)
VAR _C =
IF (
WEEKDAY ( 'Table'[ClosedDate], 2 ) IN { 6, 7 },
0,
IF (
HOUR ( 'Table'[ClosedDate] ) >= 17,
7.5,
DATEDIFF (
DATE ( YEAR ( 'Table'[ClosedDate] ), MONTH ( 'Table'[ClosedDate] ), DAY ( 'Table'[ClosedDate] ) )
+ TIME ( 9, 00, 00 ),
'Table'[ClosedDate],
MINUTE
)
)
)
VAR _Minute =
IF (
ISBLANK ( 'Table'[ClosedDate] ),
BLANK (),
_M
+ IF (
EDATE ( 'Table'[StartDate], 0 ) = EDATE ( 'Table'[ClosedDate], 0 )
&& NOT ( WEEKDAY ( 'Table'[StartDate], 2 ) IN { 6, 7 } ),
DATEDIFF ( 'Table'[StartDate], 'Table'[ClosedDate], MINUTE ),
_S + _C
)
)
RETURN
IF ( _Minute = BLANK (), BLANK (), _Minute )
Lunch Hour 13:00 to 14:00
25-10-22 10:02 31-10-22 16:58
31-10-22 14:40 31-10-22 16:48
31-10-22 12:17 31-10-22 16:50
31-10-22 15:03 31-10-22 17:00
31-10-22 15:45 31-10-22 16:44
31-10-22 14:19 31-10-22 16:44
Related
I have a date table. I have a measure that calculates the net sales. I want to calculate net sales for the same day of the week last month.
Example: Net Sales for Friday, July 1 2022 VS Net Sales for Friday, June 03, 2022.
I am using this code to get the same day last month:
Same Week Day last month =
VAR CurrentDay =
MAX ( 'Dates'[Date] )
VAR WeekDaysDelta =
WEEKDAY ( EOMONTH ( CurrentDay, -1 ) ) - WEEKDAY ( EOMONTH ( CurrentDay, -2 ) )
VAR DaysAdjust =
IF (
WeekDaysDelta > 3,
WeekDaysDelta - 7,
IF ( WeekDaysDelta < -3, WeekDaysDelta + 7, WeekDaysDelta )
)
VAR SameWeekDay =
EOMONTH ( CurrentDay, -2 ) + DAY ( CurrentDay ) + DaysAdjust
RETURN
SameWeekDay
I appreciate some help with the below problem.
I have the table
Month
Line
Amount
Jan
ST
20
Jan
AB
10
Jan
AC
2
Jan
AG
15
Feb
ST
40
Feb
AB
20
Feb
AC
4
Feb
AG
8
Mar
ST
65
Mar
AB
5
Mar
AC
6
Mar
AG
2
and I want a Matrix
Jan
Feb
Mar
AB
50.00%
50.00%
7.69%
AC
10.00%
10.00%
9.23%
AG
75.00%
20.00%
3.08%
The Value of the Matrix is a Mesure
(%) Amount ST =
SWITCH (
TRUE (),
SELECTEDVALUE ( table1[Line] ) = "AB",
DIVIDE (
SUM ( table1[Amount] ),
CALCULATE ( SUM ( table1[Amount] ), FILTER ( 'table1', table1[Line] = "ST" ) )
),
SELECTEDVALUE ( table1[Line] ) = "AC",
DIVIDE (
SUM ( table1[Amount] ),
CALCULATE ( SUM ( table1[Amount] ), FILTER ( 'table1', table1[Line] = "ST" ) )
),
SELECTEDVALUE ( table1[Line] ) = "AG", DIVIDE ( SUM ( table1[Amount] ), 4 ),
SUM ( table1[Amount] )
)
The measure works fine for AG, to test it I used in the denominator the number 4, but when I added the calculate function to filter by ST I didn't see it in the visual ???
Any ideas
Thank you
OJ
I'm not sure what are you calculating. From your measure, is this is what are you looking for?
DAX Calculation
(%) Amount ST =
VAR STAmount =
CALCULATE ( SUM ( table1[Amount] ), table1[Line] = "ST" )
RETURN
SWITCH (
TRUE (),
SELECTEDVALUE ( table1[Line] ) = "AB", DIVIDE ( SUM ( table1[Amount] ), STAmount ),
SELECTEDVALUE ( table1[Line] ) = "AC", DIVIDE ( SUM ( table1[Amount] ), STAmount ),
SELECTEDVALUE ( table1[Line] ) = "AG", DIVIDE ( SUM ( table1[Amount] ), STAmount ),
SUM ( table1[Amount] )
)
Output
I'm using the calculation below to calculate the sum of the amount for accounts >= 200
And the problem I have is when I visualize Account with Account total with excel, it gives me the total amount in all accounts.
How can I solve this?`
Account total:= CALCULATE(SUM('Table'[amount]),'Table'[Type]= "ABC",'Table'[account] >=200)
#Jos is mostly correct but there are some small inaccuracies.
This code
CALCULATE (
SUM ( 'Table'[amount] ),
'Table'[Type] = "ABC",
'Table'[account] >= 200
)
is equivalent to
CALCULATE (
SUM ( 'Table'[amount] ),
FILTER ( ALL ( 'Table'[Type] ), 'Table'[Type] = "ABC" ),
FILTER ( ALL ( 'Table'[account] ), 'Table'[account] >= 200 )
)
not
CALCULATE (
SUM ( 'Table'[amount] ),
FILTER ( ALL ( 'Table' ), 'Table'[Type] = "ABC" && 'Table'[account] >= 200 )
)
In particular, if you had a filter on, say, 'Table'[Category], this would be preserved in the former but not in the latter since ALL ( 'Table' ) removes filters on all of the columns, not just [Type] and [account].
I propose the following two nearly equivalent solutions, which are slightly more computationally efficient than filtering an entire table:
CALCULATE (
SUM ( 'Table'[amount] ),
FILTER ( VALUES ( 'Table'[Type] ), 'Table'[Type] = "ABC" ),
FILTER ( VALUES ( 'Table'[account] ), 'Table'[account] >= 200 )
)
or
CALCULATE (
SUM ( 'Table'[amount] ),
KEEPFILTERS ( 'Table'[Type] = "ABC" ),
KEEPFILTERS ( 'Table'[account] >= 200 )
)
More on KEEPFILTERS: https://www.sqlbi.com/articles/using-keepfilters-in-dax/
You should be using:
CALCULATE (
SUM ( 'Table'[amount] ),
FILTER ( 'Table', 'Table'[Type] = "ABC" && 'Table'[account] >= 200 )
)
The difference is that your current formula is equivalent to:
CALCULATE (
SUM ( 'Table'[amount] ),
FILTER ( ALL ( 'Table' ), 'Table'[Type] = "ABC" && 'Table'[account] >= 200 )
)
i.e. identical to that which I give apart from the crucial difference that it applies an (in your case implicit) ALL to the table prior to filtering. This implicit ALL will override any filters you may be applying externally.
In Oracle I would like to build a query that counts how many Mondays and Thursdays have gone by from a starting date counting both together.
For example:
from 20-MAY-18 to today (Thursday 31-MAY-18)
There has been the total count of 4 Mondays and Thursdays (2 Mondays and 2 Thursdays) have passed by from May 20 until today. I want to 4 in return in this query. If this query ran yesterday (Wednesday 30-MAY-18), I want to get 3 counts.
I am thinking subtracting the weeks from today minus 20-MAY-18
Maybe something like this:
select ( TRUNC( SYSDATE, 'IW' ) - TRUNC( TO_DATE('20-MAY-18'), 'IW' ) ) / 7 * 2 from dual;
I times it by two because of the monday and thursday. If the thurday hasn't come up yet then it gives the wrong result because of this week.
I cannot figure out to count the weekdays that have past this week to times it by the week count.
I need to be able also to change the days selected and not get stuck with only Monday and Thursday.
Maybe this will help. You can add more logic to it. I'm not sure why this has to return 3 if ran on May 30th. What is he idea? Your start/end dates are the same and number of days between also the same no matter when you run it. What should happen if his run May 30?
WITH mon_thur AS
(
SELECT to_date('20-MAY-2018') + LEVEL-1 start_date
, to_date('31-MAY-2018') end_date
, to_date('31-MAY-2018') - to_date('20-MAY-2018') days_between
FROM dual
CONNECT BY LEVEL <= to_date('31-MAY-2018') - to_date('20-MAY-2018')+1 -- days_between+1
)
SELECT count(*) number_of_mon_thu FROM
(
SELECT start_date, to_char(start_date, 'D') d_date
FROM mon_thur
)
WHERE d_date IN (2, 4)
/
The output is 4. You can replace the 'D' format to 'DY' and replace 2, 4 with WHERE d_date IN ('MON', 'THU').
You can use this to calculate the value:
Calculate the number of full days between the Monday of the week containing the start date and the Monday of this week:
( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) )
Divide it by 7 to get the number of full weeks:
/ 7
Multiply it by the number of days you want to match per week
* 2
Then adjust it to remove the Mondays and Thursdays that have been counted before the start date. This is 0 adjustment if the start day is Monday, 1 for Tuesday-Thursday and 2 for Friday-Sunday:
- DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
0, 0, -- Monday
1, 1, -- Tuesday
2, 1, -- Wednesday
3, 1, -- Thursday
4, 2, -- Friday
5, 2, -- Saturday
6, 2 -- Sunday
)
Then adjust it to include the days from the Monday of this current week to today:
+ DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
0, 1, -- Monday
1, 1, -- Tuesday
2, 1, -- Wednesday
3, 2, -- Thursday
4, 2, -- Friday
5, 2, -- Saturday
6, 2 -- Sunday
)
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE table_name ( start_date ) AS
SELECT DATE '2018-05-20' + LEVEL - 1
FROM DUAL
CONNECT BY DATE '2018-05-20' + LEVEL - 1 <= SYSDATE;
Query 1:
SELECT start_date,
TO_CHAR( start_date, 'DY' ) As day,
( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) ) / 7 * 2
- DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
0, 0, 1, 1, 2, 1, 3, 1, 4, 2, 5, 2, 6, 2 )
+ DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
0, 1, 1, 1, 2, 1, 3, 2, 4, 2, 5, 2, 6, 2 ) AS num_mon_and_thurs
FROM table_name
Results:
| START_DATE | DAY | NUM_MON_AND_THURS |
|----------------------|-----|-------------------|
| 2018-05-20T00:00:00Z | SUN | 4 |
| 2018-05-21T00:00:00Z | MON | 4 |
| 2018-05-22T00:00:00Z | TUE | 3 |
| 2018-05-23T00:00:00Z | WED | 3 |
| 2018-05-24T00:00:00Z | THU | 3 |
| 2018-05-25T00:00:00Z | FRI | 2 |
| 2018-05-26T00:00:00Z | SAT | 2 |
| 2018-05-27T00:00:00Z | SUN | 2 |
| 2018-05-28T00:00:00Z | MON | 2 |
| 2018-05-29T00:00:00Z | TUE | 1 |
| 2018-05-30T00:00:00Z | WED | 1 |
| 2018-05-31T00:00:00Z | THU | 1 |
What if I want to change it instead of monday and thursday to be tuesday, wednesday, saturday? How do I do that?
SELECT start_date,
TO_CHAR( start_date, 'DY' ) As day,
( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) ) / 7 * 3
- DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
0, 0, 1, 0, 2, 1, 3, 2, 4, 2, 5, 2, 6, 3 )
+ DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
0, 0, 1, 1, 2, 2, 3, 2, 4, 2, 5, 3, 6, 3 ) AS num_tue_wed_sat
FROM table_name;
SQLFIDDLE
I have a problem in converting a date value stored in a blob field in Oracle 11g sql command. When i execute the sql:
select dump(HIGH_VALUE) from all_tab_columns where COLUMN_NAME='TARIH'
i receive the following result;
Typ=23 Len=7: 120,116,3,6,1,1,1
I know that these numbers represent a date (not datetime), but i don't know how to extract the date from this result.
Thanks in advance,
Alper
Oracle stores dates in tables as 7-bytes
byte 1 - century + 100
byte 2 - (year MOD 100 ) + 100
byte 3 - month
byte 4 - day
byte 5 - hour + 1
byte 6 - minute + 1
byte 7 - seconds+ 1
So 120,116,3,6,1,1,1 converts to:
byte 1 - century = 120 - 100 = 20
byte 2 - year = 116 - 100 = 16
byte 3 - month = 3
byte 4 - day = 6
byte 5 - hour = 1 - 1 = 0
byte 6 - minute = 1 - 1 = 0
byte 7 - seconds = 1 - 1 = 0
So 2016-03-06T00:00:00
Oracle Setup:
CREATE TABLE file_upload ( file_blob BLOB );
INSERT INTO file_upload VALUES (
utl_raw.cast_to_raw(
CHR(120) || CHR(116) || CHR(3) || CHR(6) || CHR(1) || CHR(1) || CHR(1)
)
);
Query:
SELECT DUMP( DBMS_LOB.SUBSTR( file_blob, 7, 1 ) ) AS dmp,
TO_DATE(
TO_CHAR(
( ASCII( SUBSTR( chars, 1, 1 ) ) - 100 ) * 100
+ ASCII( SUBSTR( chars, 2, 1 ) ) - 100,
'0000'
)
|| TO_CHAR( ASCII( SUBSTR( chars, 3, 1 ) ), '00' )
|| TO_CHAR( ASCII( SUBSTR( chars, 4, 1 ) ), '00' )
|| TO_CHAR( ASCII( SUBSTR( chars, 5, 1 ) ) - 1, '00' )
|| TO_CHAR( ASCII( SUBSTR( chars, 6, 1 ) ) - 1, '00' )
|| TO_CHAR( ASCII( SUBSTR( chars, 7, 1 ) ) - 1, '00' ),
'YYYYMMDDHH24MISS'
) AS converted_date
FROM (
SELECT file_blob,
UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR( file_blob, 7, 1 ) ) AS chars
FROM file_upload
);
Output:
DMP CONVERTED_DATE
------------------------------- -------------------
Typ=23 Len=7: 120,116,3,6,1,1,1 2016-03-06 00:00:00