Conversion of sql statemnt in Dax - powerbi

I have a sql Statement with multiple cases now I have to write the statement in Dax
I tried using switch but the output is not same
the sql statement :
CASE WHEN #STRIKER!='' OR #NONSTRIKER!='' THEN (RUNS + (CASE WHEN BYES = 0 AND LEGBYES = 0 THEN OVERTHROW ELSE 0 END))
WHEN #BOWLER!='' THEN (RUNS + WIDE+ (CASE WHEN BALL.NOBALL > 0 AND (BALL.BYES > 0 OR BALL.LEGBYES > 0) THEN BALL.BYES + BALL.NOBALL + BALL.LEGBYES
WHEN BALL.NOBALL > 0 AND BALL.BYES = 0 AND BALL.LEGBYES = 0 THEN BALL.NOBALL
ELSE 0 END) + (CASE WHEN BYES = 0 AND LEGBYES = 0 THEN OVERTHROW ELSE 0 END))
ELSE GRANDTOTAL END ) AS RUNS

First, I would simplify the case statement,
I assume you have the case statements because NULLS can exist in your result? you could simply try
RUNS +
WIDE +
ISNULL(BALL.NOBALL,0) +
ISNULL(BALL.BYES,0) +
ISNULL(BALL.LEGBYES,0) +
ISNULL(OVERTHROW,0)
But if you've already got the model in PowerBI with those columns listed, you could simply add a calculated column that would sum all the columns which would ignore the nulls...
Total = RUNS + WIDE + NOBALL + BYES + LEGBYES + OVERTHROW
? but without the schema, its really hard to know what the solution might be.
good luck!

Related

Pandas calculating column based on inter-dependent lagged values

I have a dataframe that looks like the following. The rightmost two columns are my desired columns:
Open Close open_to_close close_to_next_open open_desired close_desired
0 0 0 3 0 0
0 0 4 8 3 7
0 0 1 1 15 16
The calculations are as the following:
open_desired = close_desired(prior row) + close_to_next_open(prior row)
close_desired = open_desired + open_to_close
How do I implement the following in a loop manner? I am trying to do this until the last row.
df = pd.DataFrame({'open': [0,0,0], 'close': [0,0,0], 'open_to_close': [0,4,1], 'close_to_next_open': [3,8,1]})
df['close_desired'] = 0
df['open_desired'] = 0
##First step is to create open_desired in current row which is dependent on close_desired in previous row
df['open_desired'] = df['close_desired'].shift() + df['close_to_next_open'].shift()
##second step is to create close_desired in current row which is dependent on open_desired in current row
df['close_desired'] = df['open_desired'] + df['open_to_close']
df.fillna(0,inplace=True)
The only way I can think of doing this is with iterrows()
for row, v in df.iterrows():
if row>0:
df.loc[row,'open_desired'] = df.shift(1).loc[row, 'close_desired'] + df.shift(1).loc[row, 'close_to_next_open']
df.loc[row,'close_desired'] = df.loc[row, 'open_desired'] + df.loc[row, 'open_to_close']

sas logical operators not functioning as expected

I have a condition which follows this logic Av(B^C) which is equivalent to (AvB) ^ (AvC).
Where:
A = NAF> 2
B= (COUNT_INT + COUNT_NOINT < 25)
C= (NAF> 1)
This is the condition given in the specs:
NAF> 2 OR (( COUNT_INT + COUNT_NOINT < 25) AND (NAF> 1))
This is how I coded it in sas, but its not producing the correct results. I appreciate any suggestions. Thanks.
Actually this is where it fails when I code up the array :
if (sum(count_int_arr[i],count_nonint_arr[i]) lt 25 ) and
( naf_arr[i] gt 2) or (naf_arr[i] gt 1) then check_naf_arr[i] = "bad";
The way you coded it is not what you gave in the initial specs. Your code is equivalent to (A AND B) OR C, whereas you want A OR (B AND C).
This should give you correct results:
DATA myData;
/* (...) */
DO i = 1 TO someValue;
IF (naf_arr[i] > 2) OR (SUM(count_int_arr[i], count_nonint_arr[i]) < 25 AND naf_arr[i] > 1)
THEN check_naf_arr[i] = "bad";
END;
/* (...) */
run;

How can I do this task using Z-algorithm?

In a question I am asked to find if the given string s contains two non-overlapping substrings "AB" and "BA" (the substrings can go in any order).
I have already solved this question but since I am learning Z-algorithm.Can anyone help me in that ?
I know how to find number of occurrence of a pattern in a text(by appending P and T)but I am not getting any idea how to solve this using Z algorithm ?
To find if T contains P with Z-algorithm:
S = P + '#' + T //extra char not occurring in strings
for i in 0..Length(T) - 1 do
if Z[i + Length(P) + 1] = Length(P) then
P contains T in ith position
To find if T contains both 'AB' and 'BA' without overlapping:
Sab = 'AB#' + T
Sba = 'BA#' + T
Build Zab and Zba arrays with Z-algo
PosAB_Last = Length(T) + 10 //just big value
PosAB_Prev = PosAB_Last
PosBA_Last = PosAB_Last
PosBA_Prev = PosAB_Last
for i in 0..Length(T) - 1 do
if Zab[i + 3] = 2 then
PosAB_Prev = PosAB_Last //keep two last positions of AB in text
PosAB_Last = i
//it is enough to compare positions with two last occurences of 'BA '
//so algo is linear
if (i - PosBA_Last > 1) or (i - PosBA_Prev > 1) then
Success
else
if Zba[i + 3] = 2 then
PosBA_Prev = PosBA_Last
PosBA_Last = i
if (i - PosAB_Last > 1) or (i - PosAB_Prev > 1) then
Success

Split string of digits into individual cells, including digits within parentheses/brackets

I have a column where each cell has a string of digits, ?, -, and digits in parentheses/brackets/curly brackets. A good example would be something like the following:
3????0{1012}?121-2[101]--01221111(01)1
How do I separate the string into different cells by characters, where a 'character' in this case refers to any number, ?, -, and value within the parentheses/brackets/curly brackets (including said parentheses/brackets/curly brackets)?
In essence, the string above would turn into the following (spaced apart to denote a separate cell):
3 ? ? ? ? 0 {1012} ? 1 2 1 - 2 [101] - - 0 1 2 2 1 1 1 1 (01) 1
The amount of numbers within the parentheses/brackets/curly brackets vary. There are no letters in any of the strings.
Here you are!
RegEx method:
Sub Test_RegEx()
Dim s, col, m
s = "3????0{1012}?121-2[101]--01221111(01)1"
Set col = CreateObject("Scripting.Dictionary")
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "(?:\d|-|\?|\(\d+\)|\[\d+\]|\{\d+\})"
For Each m In .Execute(s)
col(col.Count) = m
Next
End With
MsgBox Join(col.items) ' 3 ? ? ? ? 0 {1012} ? 1 2 1 - 2 [101] - - 0 1 2 2 1 1 1 1 (01) 1
End Sub
Loop method:
Sub Test_Loop()
Dim s, col, q, t, k, i
s = "3????0{1012}?121-2[101]--01221111(01)1"
Set col = CreateObject("Scripting.Dictionary")
q = "_"
t = True
k = 0
For i = 1 To Len(s)
t = (t Or InStr(1, ")]}", q) > 0) And InStr(1, "([{", q) = 0
q = Mid(s, i, 1)
If t Then k = k + 1
col(k) = col(k) & q
Next
MsgBox Join(col.items) ' 3 ? ? ? ? 0 {1012} ? 1 2 1 - 2 [101] - - 0 1 2 2 1 1 1 1 (01) 1
End Sub
Something else to look at :)
Sub test()
'String to parse through
Dim aStr As String
'final string to print
Dim finalString As String
aStr = "3????0{1012}?121-2[101]--01221111(01)1"
'Loop through string
For i = 1 To Len(aStr)
'The character to look at
char = Mid(aStr, i, 1)
'Check if the character is an opening brace, curly brace, or parenthesis
Dim result As String
Select Case char
Case "["
result = loop_until_end(Mid(aStr, i + 1), "]")
i = i + Len(result)
result = char & result
Case "("
result = loop_until_end(Mid(aStr, i + 1), ")")
i = i + Len(result)
result = char & result
Case "{"
result = loop_until_end(Mid(aStr, i + 1), "}")
i = i + Len(result)
result = char & result
Case Else
result = Mid(aStr, i, 1)
End Select
finalString = finalString & result & " "
Next
Debug.Print (finalString)
End Sub
'Loops through and concatenate to a final string until the end_char is found
'Returns a substring starting from the character after
Function loop_until_end(aStr, end_char)
idx = 1
If (Len(aStr) <= 1) Then
loop_until_end = aStr
Else
char = Mid(aStr, idx, 1)
Do Until (char = end_char)
idx = idx + 1
char = Mid(aStr, idx, 1)
Loop
End If
loop_until_end = Mid(aStr, 1, idx)
End Function
Assuming the data is in column A starting in row 1 and that you want the results start in column B and going right for each row of data in column A, here is alternate method using only worksheet formulas.
In cell B1 use this formula:
=IF(OR(LEFT(A1,1)={"(","[","{"}),LEFT(A1,MIN(FIND({")","]","}"},A1&")]}"))),IFERROR(--LEFT(A1,1),LEFT(A1,1)))
In cell C1 use this formula:
=IF(OR(MID($A1,SUMPRODUCT(LEN($B1:B1))+1,1)={"(","[","{"}),MID($A1,SUMPRODUCT(LEN($B1:B1))+1,MIN(FIND({")","]","}"},$A1&")]}",SUMPRODUCT(LEN($B1:B1))+1))-SUMPRODUCT(LEN($B1:B1))),IFERROR(--MID($A1,SUMPRODUCT(LEN($B1:B1))+1,1),MID($A1,SUMPRODUCT(LEN($B1:B1))+1,1)))
Copy the C1 formula right until it starts giving you blanks (there are no more items left to split out from the string in the A cell). In your example, need to copy it right to column AA. Then you can copy the formulas down for the rest of your Column A data.

Format long number to shorter version in Lua

I'm trying to figure out how I would go about formatting a large number to the shorter version by appending 'k' or 'm' using Lua. Example:
17478 => 17.5k
2832 => 2.8k
1548034 => 1.55m
I would like to have the rounding in there as well as per the example. I'm not very good at Regex, so I'm not sure where I would begin. Any help would be appreciated. Thanks.
Pattern matching doesn't seem like the right direction for this problem.
Assuming 2 digits after decimal point are kept in the shorter version, try:
function foo(n)
if n >= 10^6 then
return string.format("%.2fm", n / 10^6)
elseif n >= 10^3 then
return string.format("%.2fk", n / 10^3)
else
return tostring(n)
end
end
Test:
print(foo(17478))
print(foo(2832))
print(foo(1548034))
Output:
17.48k
2.83k
1.55m
Here a longer form, which uses the hint from Tom Blodget.
Maybe its not the perfect form, but its a little more specific.
For Lua 5.0, replace #steps with table.getn(steps).
function shortnumberstring(number)
local steps = {
{1,""},
{1e3,"k"},
{1e6,"m"},
{1e9,"g"},
{1e12,"t"},
}
for _,b in ipairs(steps) do
if b[1] <= number+1 then
steps.use = _
end
end
local result = string.format("%.1f", number / steps[steps.use][1])
if tonumber(result) >= 1e3 and steps.use < #steps then
steps.use = steps.use + 1
result = string.format("%.1f", tonumber(result) / 1e3)
end
--result = string.sub(result,0,string.sub(result,-1) == "0" and -3 or -1) -- Remove .0 (just if it is zero!)
return result .. steps[steps.use][2]
end
print(shortnumberstring(100))
print(shortnumberstring(200))
print(shortnumberstring(999))
print(shortnumberstring(1234567))
print(shortnumberstring(999999))
print(shortnumberstring(9999999))
print(shortnumberstring(1345123))
Result:
> dofile"test.lua"
100.0
200.0
1.0k
1.2m
1.0m
10.0m
1.3m
>
And if you want to get rid of the "XX.0", uncomment the line before the return.
Then our result is:
> dofile"test.lua"
100
200
1k
1.2m
1m
10m
1.3m
>