I am looking to speed up this calculation that takes a minute or two to load each time I add a different filter view on the page.
The base measure just calculates the total logins in a rolling 3 month which works as expected.
TotalLoginsIn90 =
CALCULATE (
SUM ( [Logins] ),
DATESINPERIOD ( 'Calendar'[Date], LASTDATE ( Logins[Date] ), -3, MONTH )
)
I am now looking to identify in each month the amount of users that make over 3 logins in each month.
CustLoginIn90 =
CALCULATE (
SUMX ( DISTINCT ( Logins[Customer Number)] ), 1 ),
FILTER (
VALUES ( Logins[Cust Customer Number (Numeric)] ),
[TotalLoginsIn90] > 3
)
)
or
CustLoginIn90 =
CALCULATE (
DISTINCT ( Logins[Customer Number] ),
FILTER (
VALUES ( Logins[Cust Customer Number (Numeric)] ),
[TotalLoginsIn90] > 3
)
)
each of these takes its sweet time to calculate but ends up with the correct amount.
Is there any way to speed up these measures?
Thanks for the help!
I would recommend making the TotalLoginsIn90 as a calculated column instead of a measure so it only needs to be calculated once (per report refresh).
TotalLoginsIn90 =
CALCULATE (
SUM ( [Logins] ),
DATESINPERIOD (Logins[Date], Logins[Date], -3, MONTH)
)
That also allows you to write a very simple condition for your CustLoginIn90 measure:
CustLoginIn90 = SUMX(Logins, IF(Logins[TotalLogins90] > 3, 1, 0))
Related
How can I get the total working hours scheduled with this format?
Expected output should be 46.
Not the prettiest things, but here are two ways to tackle it
=ARRAYFORMULA(
SUM(
IFERROR(
INDEX(SPLIT(TRANSPOSE(A2:G2)," - ",FALSE,TRUE),0,2)-
INDEX(SPLIT(TRANSPOSE(A2:G2)," - ",FALSE,TRUE),0,1)))*
24)
or
=ARRAYFORMULA(
SUM(
IFERROR(
REGEXEXTRACT(A2:G2,"- (\d+:\d+)")-
REGEXEXTRACT(A2:G2,"^(\d+:\d+)")))*
24)
Either way, we extract the second values then subtract the first values from that, sum it, and multiply it by 24.
For overnight shifts, try this
=ARRAYFORMULA(
SUM(
IFERROR(
IF(
--REGEXEXTRACT(A2:G2,"- (\d+:\d+)")<(--REGEXEXTRACT(A2:G2,"^(\d+:\d+)")),
1+REGEXEXTRACT(A2:G2,"- (\d+:\d+)")-
REGEXEXTRACT(A2:G2,"^(\d+:\d+)"),
REGEXEXTRACT(A2:G2,"- (\d+:\d+)")-
REGEXEXTRACT(A2:G2,"^(\d+:\d+)")))*
24))
in [hh]:mm:ss
=ARRAYFORMULA(
TEXT(
SUM(
IFERROR(
IF(
--REGEXEXTRACT(A2:G2,"- (\d+:\d+)")<(--REGEXEXTRACT(A2:G2,"^(\d+:\d+)")),
1+REGEXEXTRACT(A2:G2,"- (\d+:\d+)")-
REGEXEXTRACT(A2:G2,"^(\d+:\d+)"),
REGEXEXTRACT(A2:G2,"- (\d+:\d+)")-
REGEXEXTRACT(A2:G2,"^(\d+:\d+)")))),
"[hh]:mm:ss"))
Why is this formula not working? Trying to find the next date equal or greater than today in column K but using a query to filter out some items. Thanks for the help.
=ArrayFormula(QUERY(Sheet1!B6:K,"select K where B contains '303'")TO_DATE(MIN(if(Sheet1!K:K>=today(),Sheet1!K:K'!K:K))))
Try:
=MIN(
QUERY(
Sheet1!B6:K,
"SELECT K
WHERE B CONTAINS '303'
AND K >= toDate(now())"
)
)
Or:
=MIN(
FILTER(
Sheet1!K6:K,
REGEXMATCH(Sheet1!B6:B, "303"),
Sheet1!K6:K >= TODAY()
)
)
I have a single group of constant:
const (
a = 100
b = 200
c = 300
)
I was wondering if there is any way to use iota keyword instead of assigning each value manually?
As described in the official reference, it is possible to use bitwise shift with iota to increase numbers, but I want to increase by a fixed number like 100 for example.
const (
_ = iota * 100
a
b
c
)
https://play.golang.org/p/V-2Uv9JPj6g
I have two matrices of different dimensions and I want to compare if any of the elements in their first columns match (and eventually remove rows where there is a match). Looping just takes too much time so I am trying vectorized version but nothing I've tried worked. Any help would be much appreciated!
Example.
A = magic(3);
B = magic(6);
UpTo = min( size( A, 1 ), size( B, 1 ) );
CommonRows = B(1 : UpTo, 1) == A(1 : UpTo, 1);
B( CommonRows, : ) = [] % B with rows of same element in column 1 removed
This is the last thing I tried and almost got it but doesn't work when I have repeating values in both matrices.
[C,iC]=setdiff(A(:,1),B(:,1))
[D,iD]=intersect(A(:,1),B(:,1))
newA=A(iC,:)
newBtemp=[A(iD,:);B]
newB=sort(newBtemp)
But I think I got it now finally:
common=ismember(A(:,1),B(:,1))
temp=A(common,:)
A(common,:)=[]
newB=sort([temp;B])
Given an input of logical times and a unique key for each time, how do I give back a total sequence of logical times (which may be broken up) identifying each key 'present' for that time?
For example with logical times as simple integers (that can be incremented or decremented), and keys which can compared:
type LogicalTime = Int
type Key = Char
-- Not necessarily ordered
skipList :: [(LogicalTime, LogicalTime, Key)]
skipList =
[ (100, 200, 'A')
, (201, 300, 'B')
, ( 20, 400, 'C')
, (125, 150, 'D')
, (151, 250, 'E')
]
expected :: [(LogicalTime, LogicalTime, [Key])]
expected =
[ ( 20, 99, ['C'])
, (100, 124, ['A','C'])
, (125, 150, ['A','C','D'])
, (151, 200, ['A','C','E'])
, (201, 250, ['B','C','E'])
, (251, 300, ['B','C'])
, (301, 400, ['C'])
]
One may naively iterate over the entire range found and loop through every key entry to calculate this, though I'm looking for a more efficient approach.
(This is not language specific)
Each interval (start, end, key) triggers two events: add(key,start) and remove(key,end). Generate these events while iterating over the list of intervals, then sort the events by their time (start or end). Then you can go through the sorted events, generate an interval ending before the events with active keys and update the counts of keys for the next interval.
Here is some python code:
events = []
for start,end,key in skipList:
events.extend([(start-1, 1, key), (end, -1, key)])
events.sort()
startTime,_,firstKey = events.pop(0)
activeKeys = {firstKey:1}
expected = []
for time,delta,key in events:
currentKeys = [k for k in activeKeys if activeKeys[k] > 0]
currentKeys.sort()
if startTime < time:
expected.append((startTime+1, time, currentKeys))
if not key in activeKeys:
activeKeys[key] = 0
activeKeys[key] += delta
startTime = time
For your example skipList the output as expected is generated.