Power BI DAX : multi-column and multi-row condition and group by 2 columns - dax

Folks, I am trying to create a calculated column/measures and experiencing issues.
My Data-set looks like this:
City
Building Name
Test Date
Component
Test Result
Calculated Result
-
-
-
-
-
-
City1
Build1
1/3/2014
Component A
Pass
None
City1
Build1
1/11/2014
Component 1
Fail
Fail1
City1
Build1
1/11/2014
Component 2
Pass
Fail1
City1
Build1
1/11/2014
Component 3
Pass
Fail1
City1
Build1
1/06/2014
Component A
Fail
MultiFail
City1
Build1
1/06/2014
Component 1
Fail
MultiFail
City1
Build1
1/06/2014
Component 2
Pass
MultiFail
City1
Build1
1/06/2014
Component 3
Fail
MultiFail
I am looking at Component & Test Result columns, count list of Fails - grouped by Building Name and Date; then generate Calculated result depending on the number of components failed.
If Single component Test Result = fail - then Calculated Result = Fail1
If CountA(components Test Result = fail) <=2 then Calculated Result = Fail2
If CountA(components Test Result = fail) > 2 then Calculated Result = MultiFail
If Component1 AND ComponentA Test Result = Fail then Calculated Result = FailMail
So far, I tried various ways in solving this with a step ahead and 2 steps behind:
I created a calculated column to count # Fails to be used for Calculated Result and struggling to generate Calculated Result.
Tests_Failed =
CALCULATE(COUNT(Table[TestResult]),FILTER(Table,Table[date]=MAX(Table[date])
&& Table[TestResult]="Fail"))
Another way I tried approaching the problem
Calculated Result =
VAR Component = Table[Component]
VAR Date1 = Table[Test date]
VAR Build = Table[Building Name]
RETURN
CALCULATE(DISTINCTCOUNT('Table'[Component]), ALL(Table), FILTER('Table',
'Table'[Test Result]="Fail" && 'Table'[date] = Date1 &&
'Table'[Building Name]=Build)))

Can you try this
Measure =
VAR _1 =
CALCULATE (
CALCULATE (
DISTINCTCOUNT ( 'Table'[Component] ),
FILTER ( 'Table', 'Table'[Test Result] = "Fail" )
),
ALLEXCEPT ( 'Table', 'Table'[Building Name], 'Table'[Test Date] )
)
VAR _2 =
SWITCH (
TRUE (),
ISBLANK ( _1 ) = TRUE (), "None",
_1 = 1, "Fail1",
"MultiFail"
)
RETURN
_2

Related

Performance enhancement in DAX query

I have Power BI DAX query used in a measure. It takes longer time to execute. Can anyone please help me with this?
MEASURE FACT_CONSOL_BALANCE_OL[Measure 4] =
SWITCH (
TRUE (),
CONTAINS (
DIM_ANALYTIC_STRUCT_ACCOUNT,
DIM_ANALYTIC_STRUCT_ACCOUNT[STRUCTURE_NODE (groups)], "1 - CURRENT ASSETS"
), SUM ( FACT_CONSOL_BALANCE_OL[BALANCE] ),
CONTAINS (
DIM_ANALYTIC_STRUCT_ACCOUNT,
DIM_ANALYTIC_STRUCT_ACCOUNT[STRUCTURE_NODE (groups)], "2 - NON - CURRENT ASSETS"
), SUM ( FACT_CONSOL_BALANCE_OL[BALANCE] ),
SUM ( FACT_CONSOL_BALANCE_OL[BALANCE] ) * -1
)
Performance Result on DAX Studio:
Can you please try this code, see if It solves your problem. I tried to write it without contains() function.
MEASURE FACT_CONSOL_BALANCE_OL[Measure 4] =
SUMX (
FACT_CONSOL_BALANCE_OL,
VAR Balance =
SWITCH (
RELATED ( DIM_ANALYTIC_STRUCT_ACCOUNT[STRUCTURE_NODE (groups)] ),
"1 - CURRENT ASSETS", FACT_CONSOL_BALANCE_OL[BALANCE],
"2 - NON - CURRENT ASSETS", FACT_CONSOL_BALANCE_OL[BALANCE],
FACT_CONSOL_BALANCE_OL[BALANCE] * -1
)
RETURN
Balance
)

Not able to select the 2nd row in a webtable usng description lanugauge in UFT

I have written the below piece of code to pick a row from web table to process it. The code picks/opens the first row successfully, however, when it is trying to double click the second row, it errors out with an error "Unspecified error". The web table has 7 rows, nevertheless, it is failing. Can some one point out what could be the reason for the failure please?
Set objDesc = Description.Create
objDesc("micclass").Value = "WebTable"
objDesc("html tag").Value = "Table"
Set objList = Browser("3 - Employee Assign Benefits").Page("3 - Employee Assign Benefits").Frame("APPFRAMEWORK").ChildObjects(objDesc)
oCount = objList.Count
For k =0 To oCount - 1
colName = objList(k).GetRoproperty("cols")
If Trim(colName) = 21 Then 'This is the right table
objList(k).Highlight
rows= objList(k).GetROProperty("rows")
For i = 1 To rows
x = objList(k).ChildItem(i,1,"WebElement",0).GetROProperty("abs_x")
y = objList(k).ChildItem(i,1,"WebElement",0).GetROProperty("abs_y")
Wait(2)
Set obj = CreateObject("Mercury.DeviceReplay")
obj.MouseDblClick x,y,LEFT_MOUSE_BUTTON
Call ClickVerifyElement(Browser("3 - Employee Assign Benefits").Page("3 - Employee Assign Benefits").Frame("APPFRAMEWORK").WebEdit("ben_elig_dte"), "ben_elig_dte", "WebEdit", Parameter("elig_date"))
Call ClickVerifyElement(Browser("3 - Employee Assign Benefits").Page("3 - Employee Assign Benefits").Frame("APPFRAMEWORK").WebList("emp_state_withd_opt_decode"), "emp_state_withd_opt_decode", "WebList", Parameter("withhold_ind"))
Browser("3 - Employee Assign Benefits").Page("3 - Employee Assign Benefits").Frame("APPFRAMEWORK").WebButton("Save").Click
Next
Exit For
End If
Next

Getting Repository dependencies

I'm using Informatica with Oracle RDBMS. Lately I've been struggling a bit.
I got an assignment to query the dependencies between each Model/Workflow , so the desired result will look something like this:
GRAND_MODEL | GRAND_WORKFLOW | WAIT_4_MODEL | WAIT_4_WORKFLOW
DWH_Model1 WF_workflow1 DWH_Model3 WF_Workflow3_1
DWH_Model1 WF_workflow1 DWH_Model4 WF_Workflow4_1
DWH_Model2 WF_workflow2_1 DWH_Model1 WF_Workflow1
Which means, WF_workflow1 in model DWH_Model1 waits for workflow WF_Workflow3_1 in model DWH_Model3 ETC....
We have 3 types of workflows , DELTA (will contains the word DELTA) DWH (same here) and CALC(same here). A workflow that waits uses an EVENT that will contain both of the models names, and a workflow that flags contain a CMD that contain the grand_model name.
So far We've come up with this:
SELECT DISTINCT OA.SUBJ_NAME AS GRAND_MODEL,
OL.SUBJ_NAME AS WAIT_4_MODEL_NAME,
REP.WORKFLOW_NAME AS WAIT_4_WORKFLOW_NAME,
A.FLAG_NAME,
CASE
WHEN INSTR(UPPER(A.FLAG_NAME), 'DWH') > 0 THEN
'DWH'
WHEN INSTR(UPPER(REP.WORKFLOW_NAME), 'DELTA') > 0 THEN
'DELTA'
ELSE
'CALC'
END CONNECTION_NAME
FROM OPB_SUBJECT#TO_INFORMATICA_ADMIN OL,
OPB_SUBJECT#TO_INFORMATICA_ADMIN OA,
OPB_TASK#TO_INFORMATICA_ADMIN T,
OPB_TASK#TO_INFORMATICA_ADMIN TL,
OPB_TASK_INST#TO_INFORMATICA_ADMIN TI,
REP_SESSION_INSTANCES#TO_INFORMATICA_ADMIN REP,
(SELECT T.TASK_ID,
SUBSTR(T.ATTR_VALUE,
LENGTH(T.ATTR_VALUE) + 2 -
INSTR(REVERSE(T.ATTR_VALUE), '/')) FLAG_NAME
FROM OPB_TASK_ATTR#TO_INFORMATICA_ADMIN T
WHERE T.TASK_TYPE = 60
AND INSTR(REVERSE(T.ATTR_VALUE), '/') > 0) A,
(SELECT T.TASK_ID,
T.SUBJECT_ID,
SUBSTR(T.PM_VALUE,
LENGTH(T.PM_VALUE) + 2 -
INSTR(REVERSE(T.PM_VALUE), '/')) FLAG_NAME
FROM OPB_TASK_VAL_LIST#TO_INFORMATICA_ADMIN T
WHERE INSTR(REVERSE(T.PM_VALUE), '/') > 0) L
WHERE OL.SUBJ_ID = L.SUBJECT_ID
AND A.TASK_ID = T.TASK_ID
AND T.SUBJECT_ID = OA.SUBJ_ID
AND A.FLAG_NAME = L.FLAG_NAME
AND OL.SUBJ_NAME <> OA.SUBJ_NAME
AND L.TASK_ID = TL.TASK_ID
AND TL.TASK_ID = TI.TASK_ID
AND TI.WORKFLOW_ID = REP.WORKFLOW_ID
This query works! The problem is, I'm getting worklets as workflows as well, so some of the times the last joins fails. I don't know how to avoid it..

Criterion on object relation list field

Using eZ Publish 2014.11, I'd like to filter search results on an objectrelationlist field.
I use this code (I removed all parts that are not related to the objectrelatiolist field) :
$query->query = new Criterion\LogicalAnd(
array(
// ...
new Criterion\Field( 'myField', Criterion\Operator::EQ, my_value ),
// ...
)
);
According to the profiler, the resulting query looks like this (I removed all parts that are not related to the objectrelatiolist field) :
SELECT
-- ...
AND `ezcontentobject`.`id` IN (
SELECT
`contentobject_id`
FROM
`ezcontentobject_attribute`
WHERE
(
-- ...
AND (
`contentclassattribute_id` IN ('342')
AND `sort_key_string` = my_value
)
)
)
-- ...
Apparenty in the database sort_key_string is empty for the field row (in spite the existing relation shown in data_text field):
*************************** 385. row ***************************
attribute_original_id: 0
contentclassattribute_id: 342
contentobject_id: 137
data_float: 0
data_int: NULL
data_text: <?xml version="1.0" encoding="utf-8"?>
<related-objects><relation-list><relation-item priority="1" contentobject-id="67" contentobject-version="1" node-id="69" parent-node-id="2" contentclass-id="43" contentclass-identifier="theme" contentobject-remote-id="00162a519495cd3b956192ea30b68761"/><relation-item priority="2" contentobject-id="68" contentobject-version="1" node-id="70" parent-node-id="2" contentclass-id="43" contentclass-identifier="theme" contentobject-remote-id="853215e40ca057a787a8cea9cdd5ddce"/></relation-list></related-objects>
data_type_string: ezobjectrelationlist
id: 614
language_code: fre-FR
language_id: 2
sort_key_int: 0
sort_key_string:
version: 1
So my question is : is there any way to search content using a criterion on an objectrelationlist ?
I should have use the fieldRelation criterion like this :
new Criterion\FieldRelation( 'myField', Criterion\Operator::IN, array(my_value) ),

Show duplicates in internal table

Each an every item should have an uniquie SecondNo + Drawing combination. Due to misentries, some combinations are there two times.
I need to create a report with ABAP which identifies those combinations and does not reflect the others.
Item: SecNo: Drawing:
121 904 5000 double
122 904 5000 double
123 816 5100
124 813 5200
125 812 4900 double
126 812 4900 double
127 814 5300
How can I solve this? I tried 2 approaches and failed:
Sorting the data and tried to print out each one when the value of the upper row is equal to the next value
counting the duplicates and showing all of them which are more then one.
Where do I put in the condition? in the loop area?
I tried this:
REPORT duplicates.
DATA: BEGIN OF lt_duplicates OCCURS 0,
f2(10),
f3(10),
END OF lt_duplicates,
it_test TYPE TABLE OF ztest WITH HEADER LINE,
i TYPE i.
SELECT DISTINCT f2 f3 FROM ztest INTO TABLE lt_duplicates.
LOOP AT lt_duplicates.
IF f2 = lt_duplicates-f2 AND f3 = lt_duplicates-f3.
ENDIF.
i = LINES( it_test ).
IF i > 1.
LOOP AT it_test.
WRITE :/ it_test-f1,it_test-f2,it_test-f3.
ENDLOOP.
ENDIF.
ENDLOOP.
From ABAP 7.40, you may use the GROUP BY constructs with the GROUP SIZE words so that to take into account only the groups with at least 2 elements.
ABAP statement LOOP AT ... GROUP BY ( <columns...> gs = GROUP SIZE ) ...
Loop at grouped lines:
Either LOOP AT GROUP ...
Or ... FOR ... IN GROUP ...
ABAP expression ... VALUE|REDUCE|NEW type|#( FOR GROUPS ... GROUP BY ( <columns...> gs = GROUP SIZE ) ...
Loop at grouped lines: ... FOR ... IN GROUP ...
For both constructs, it's possible to loop at the grouped lines in two ways:
* LOOP AT GROUP ...
* ... FOR ... IN GROUP ...
Line# Item SecNo Drawing
1 121 904 5000 double
2 122 904 5000 double
3 123 816 5100
4 124 813 5200
5 125 812 4900 double
6 126 812 4900 double
7 127 814 5300
You might want to produce the following table containing the duplicates:
SecNo Drawing Lines
904 5000 [1,2]
812 4900 [5,6]
Solution with LOOP AT ... GROUP BY ...:
TYPES: BEGIN OF t_line,
item TYPE i,
secno TYPE i,
drawing TYPE i,
END OF t_line,
BEGIN OF t_duplicate,
secno TYPE i,
drawing TYPE i,
num_dup TYPE i, " number of duplicates
lines TYPE STANDARD TABLE OF REF TO t_line WITH EMPTY KEY,
END OF t_duplicate,
t_lines TYPE STANDARD TABLE OF t_line WITH EMPTY KEY,
t_duplicates TYPE STANDARD TABLE OF t_duplicate WITH EMPTY KEY.
DATA(table) = VALUE t_lines(
( item = 121 secno = 904 drawing = 5000 )
( item = 122 secno = 904 drawing = 5000 )
( item = 123 secno = 816 drawing = 5100 )
( item = 124 secno = 813 drawing = 5200 )
( item = 125 secno = 812 drawing = 4900 )
( item = 126 secno = 812 drawing = 4900 )
( item = 127 secno = 814 drawing = 5300 ) ).
DATA(expected_duplicates) = VALUE t_duplicates(
( secno = 904 drawing = 5000 num_dup = 2 lines = VALUE #( ( REF #( table[ 1 ] ) ) ( REF #( table[ 2 ] ) ) ) )
( secno = 812 drawing = 4900 num_dup = 2 lines = VALUE #( ( REF #( table[ 5 ] ) ) ( REF #( table[ 6 ] ) ) ) ) ).
DATA(actual_duplicates) = VALUE t_duplicates( ).
LOOP AT table
ASSIGNING FIELD-SYMBOL(<line>)
GROUP BY
( secno = <line>-secno
drawing = <line>-drawing
gs = GROUP SIZE )
ASSIGNING FIELD-SYMBOL(<group_table>).
IF <group_table>-gs >= 2.
actual_duplicates = VALUE #( BASE actual_duplicates
( secno = <group_table>-secno
drawing = <group_table>-drawing
num_dup = <group_table>-gs
lines = VALUE #( FOR <line2> IN GROUP <group_table> ( REF #( <line2> ) ) ) ) ).
ENDIF.
ENDLOOP.
WRITE : / 'List of duplicates:'.
SKIP 1.
WRITE : / 'Secno Drawing List of concerned items'.
WRITE : / '---------- ---------- ---------------------------------- ...'.
LOOP AT actual_duplicates ASSIGNING FIELD-SYMBOL(<duplicate>).
WRITE : / <duplicate>-secno, <duplicate>-drawing NO-GROUPING.
LOOP AT <duplicate>-lines INTO DATA(line).
WRITE line->*-item.
ENDLOOP.
ENDLOOP.
ASSERT actual_duplicates = expected_duplicates. " short dump if not equal
Output:
List of duplicates:
Secno Drawing List of concerned items
---------- ---------- ---------------------------------- ...
904 5000 121 122
812 4900 125 126
Solution with ... VALUE type|#( FOR GROUPS ... GROUP BY ...:
DATA(actual_duplicates) = VALUE t_duplicates(
FOR GROUPS <group_table> OF <line> IN table
GROUP BY
( secno = <line>-secno
drawing = <line>-drawing
gs = GROUP SIZE )
( secno = <group_table>-secno
drawing = <group_table>-drawing
num_dup = <group_table>-gs
lines = VALUE #( FOR <line2> IN GROUP <group_table> ( REF #( <line2> ) ) ) ) ).
DELETE actual_duplicates WHERE num_dup = 1.
Note: for deleting non-duplicates, instead of using an additional DELETE statement, it can be done inside the VALUE construct by adding a LINES OF COND construct which adds 1 line if group size >= 2, or none otherwise (if group size = 1):
...
gs = GROUP SIZE )
( LINES OF COND #( WHEN <group_table>-gs >= 2 THEN VALUE #( "<== new line
( secno = <group_table>-secno
...
... REF #( <line2> ) ) ) ) ) ) ) ). "<== 3 extra right parentheses
You can use AT...ENDAT for this, provided that you arrange the fields correctly:
TYPES: BEGIN OF t_my_line,
secno TYPE foo,
drawing TYPE bar,
item TYPE baz, " this field has to appear AFTER the other ones in the table
END OF t_my_line.
DATA: lt_my_table TYPE TABLE OF t_my_line,
lt_duplicates TYPE TABLE OF t_my_line.
FIELD-SYMBOLS: <ls_line> TYPE t_my_line.
START-OF-WHATEVER.
* ... fill the table ...
SORT lt_my_table BY secno drawing.
LOOP AT lt_my_table ASSIGNING <ls_line>.
AT NEW drawing. " whenever drawing or any field left of it changes...
FREE lt_duplicates.
ENDAT.
APPEND <ls_line> TO lt_duplicates.
AT END OF drawing.
IF lines( lt_duplicates ) > 1.
* congrats, here are your duplicates...
ENDIF.
ENDAT.
ENDLOOP.
I needed simply to report duplicate lines in error based on two fields so used the following.
LOOP AT gt_data INTO DATA(gs_data)
GROUP BY ( columnA = gs_data-columnA columnB = gs_data-columnB
size = GROUP SIZE index = GROUP INDEX ) ASCENDING
REFERENCE INTO DATA(group_ref).
IF group_ref->size > 1.
PERFORM insert_error USING group_ref->columnA group_ref->columnB.
ENDIF.
ENDLOOP.
Here is my 2p worth, you could cut some out of this depending on what you want to do, and you should consider the amount of data being processed too. This method is only really for smaller sets.
Personally I like to prevent erroneous records at the source. Catching an error during input. But if you do end up in a pickle there is definitely more than one way to solve the issue.
TYPES: BEGIN OF ty_itab,
item TYPE i,
secno TYPE i,
drawing TYPE i,
END OF ty_itab.
TYPES: itab_tt TYPE STANDARD TABLE OF ty_itab.
DATA: lt_itab TYPE itab_tt,
lt_itab2 TYPE itab_tt,
lt_itab3 TYPE itab_tt.
lt_itab = VALUE #(
( item = '121' secno = '904' drawing = '5000' )
( item = '122' secno = '904' drawing = '5000' )
( item = '123' secno = '816' drawing = '5100' )
( item = '124' secno = '813' drawing = '5200' )
( item = '125' secno = '812' drawing = '4900' )
( item = '126' secno = '812' drawing = '4900' )
( item = '127' secno = '814' drawing = '5300' )
).
APPEND LINES OF lt_itab TO lt_itab2.
APPEND LINES OF lt_itab TO lt_itab3.
SORT lt_itab2 BY secno drawing.
DELETE ADJACENT DUPLICATES FROM lt_itab2 COMPARING secno drawing.
* Loop at what is hopefully the smaller itab.
LOOP AT lt_itab2 ASSIGNING FIELD-SYMBOL(<line>).
DELETE TABLE lt_itab3 FROM <line>.
ENDLOOP.
* itab1 has all originals.
* itab2 has the unique.
* itab3 has the duplicates.

Resources