I want to find the difference between the sum of all the common elements between 2 tables.
We have one large table (Table A)
You can observe that neither the id, nor the date can be used individually as a unique identifier.
Based on certain filters(one of it is date), we have to create 2 tables:
We then have to find the difference between the sum of all the common elements.
Table 1 and 2 may not be real tables and could be simply virtual tables (defined using VAR) declared in order to create the measure.
I have tried the following code:
Difference =
VAR
Table1= ADDCOLUMNS('TableA', "id", CALCULATE(VALUES('TableA'[Id]), ALL('Date'),ALL('TableA'), USERELATIONSHIP('Date'[As of Date], Previous_Date[Previous_Date]),USERELATIONSHIP('Date'[As of Date], 'TableA'[Date])), "Value", 'TableA'[Value] )
VAR
Table2= ADDCOLUMNS('TableA', "id", CALCULATE(VALUES('TableA'[Id]),ALL('TableA'), USERELATIONSHIP('Date'[As of Date], 'TableA'[Date])),"Value", 'TableA'[Value] )
VAR
abc = CALCULATE(SUMX(Table1,IF(VALUES('TableA'[Id]) IN Table1 && VALUES('TableA'[Id]) in Table2,Table1[Value])) )
VAR
pqr = CALCULATE(SUMX(Table2,IF(VALUES('TableA'[Id]) IN Table1 && VALUES('TableA'[Id]) in Table2,Table2[Value])) )
RETURN
abc-pqr
Pre-requisite :- Change the Data Type of your id columns to Text in both the tables.
Then, Create this Calculated Column in Table1 :-
Common_NotCommon_Table1 =
Var out1 = LOOKUPVALUE(Table2[id],Table2[id],Table1[id])
Var out2 = IF(out1 <> "", "Common","Not-Common")
return out2
Then Create this Calculated Column in Table2 Likewise :-
Common_NotCommon_Table2 =
Var out1 = LOOKUPVALUE(Table1[id],Table1[id],Table2[id])
Var out2 = IF(out1 <> "", "Common","Not-Common")
return out2
Then Create the two Measures to find the Sum - this can be created in any of your tables.
Sum_Common_Table1 = CALCULATE(SUM(Table1[corresponding value]), FILTER(Table1, Table1[Common_NotCommon_Table1] = "Common"))
Sum_Common_Table2 = CALCULATE(SUM(Table2[corresponding value]), FILTER(Table2, Table2[Common_NotCommon_Table2] = "Common"))
Then Create the Difference Measure in any one of the Table:-
Common_Diff = [Sum_Common_Table2] - [Sum_Common_Table1]
The Output as Expected looks like,
Kindly accept the answer if it helps and let me know, how it works for you.
Related
I have two tables FACT AND DIM as follow:
the tables are linked to each other using the SRGT key.
I want to calculate the average of ANSWER_VALUES
I was able to do it with SQL using the query below:
SELECT AVG(DIM.ANSWER_VALUE)
FROM FACT_SURVEY FACT
INNER JOIN DIM_QUESTION_ANSWER DIM
ON FACT.ANSWER_SRGT = DIM.ANSWER_SRGT
I tried to write the DAX formula, but it didn't work:
AVGSCORE =
VAR MTABLE = SUMMARIZE(FACT_SURVEY,FACT_SURVEY[RESPONDENT_SRGT])
VAR MTABLE0 = ADDCOLUMNS(MTABLE,"answer",CALCULATE(AVERAGE(FACT_SURVEY[ANSWER_SRGT])))
VAR AVGTABLE = ADDCOLUMNS(MTABLE0,"value",CALCULATE(AVERAGE(DIM_ANSWER[ANSWER_VALUE])))
RETURN ???
Use AVERAGEX with RELATED:
AVGSCORE :=
AVERAGEX(
FACT_SURVEY,
RELATED( DIM_ANSWER[ANSWER_VALUE] )
)
Hi i have an issue i cant fix in PowerBI i dont understand DAX that mutch.
I have a half solution in DAX and an example what i have tryed.
I have the solution in SQL.
WANTED RESULT
I need to get the "time" result summed up
that have values between the two selected values.
IMPORTANT if one rows of values starts before AND after the selected values then the operation was active that time and shall be included.
#sdate = '2020'
#sdate = '2021'
Select *
From #temp
where (datepart(year,startdate) <= #sdate and datepart(year,enddate))
or (startdate between #sdate and #edate)
or (enddate between #sdate and #edate)
If i do it in SSMS i get the right rows
But in PowerBI i have some issue
I need to be able to choose två year
Year from startdate
Year from enddate
This part work but not the full solution
I just get row 3 and 4 as it sould of this solution.
UPDATED
NOW I DONT EVEN GET THIS PART RIGHT
I want all the green to include and exclude the red
Antal (under året) =
var SelectedYearStart = CONVERT(SELECTEDVALUE(TEST[startdate].[Year]), INTEGER)
var SelectedYearEnd = CONVERT(SELECTEDVALUE(TEST[enddate].[Year]), INTEGER)
return CALCULATE(SUM(TEST[time]),ALLCROSSFILTERED(TEST),year(TEST[startdate])<=SelectedYearStart , year(TEST[enddate])>=SelectedYearEnd)
My guess was this
Antal (under året) =
var SelectedYearStart = CONVERT(SELECTEDVALUE(TEST[startdate].[Year]), INTEGER)
var SelectedYearEnd = CONVERT(SELECTEDVALUE(TEST[enddate].[Year]), INTEGER)
return CALCULATE(SUM(TEST[time]),ALLCROSSFILTERED(TEST),year(TEST[startdate])<=SelectedYearStart , year(TEST[enddate])>=SelectedYearEnd || DATESBETWEEN(TEST[startdate],SelectedYearStart,SelectedYearEnd || DATESBETWEEN(TEST[enddate],SelectedYearStart,SelectedYearEnd)))
But then i get this error
TEST DATA
declare #sdate nvarchar(4)
declare #edate nvarchar(4)
set #sdate = '2020'
set #edate = '2021'
select #sdate sdate
select #edate edate
DEclare #temp table (time decimal(18,2) , startdate date, enddate date)
INSERT INTO #temp
SELECT 5.0,'2019-01-01','2020-12-01' union all --
SELECT 5.0,'2021-01-01','2022-12-01' union all --
select 5.0,'2020-01-01','2021-12-01' union all
select 5.0,'2019-01-01','2022-12-01' union all --
select 5.0,'2019-01-01','2019-12-01' union all --
select 5.0,'2022-01-01','2022-12-01' union all
select 5.0,'2020-01-01','2020-12-01' union all
select 5.0,'2021-01-01','2021-12-01'
--select 5.0,'2020-01-01','3000-01-01' --EXTRA
SELECT *
into TEST
FROM #temp
--ORDER BY startdate,enddate
You need something like this:
var SelectedYearStart = SELECTEDVALUE(TEST[startdate].[Year])
var SelectedYearEnd = SELECTEDVALUE(TEST[enddate].[Year])
return CALCULATE(SUM(TEST[time]),
ALL ( TEST[startdate].[Year]),
ALL ( TEST[enddate].[Year]),
KEEPFILTERS(
(Year(TEST[startdate]) <= SelectedYearStart &&
Year(TEST[enddate]) >= SelectedYearEnd)
|| (Year(TEST[startdate]) >= SelectedYearStart &&
Year(TEST[startdate]) <= SelectedYearEnd)
|| (Year(TEST[enddate]) >= SelectedYearStart &&
Year(TEST[enddate]) <= SelectedYearEnd))
)
First you need to clear the filters on the table that are created via the two slicers (startdate.Year and enddate.Year)
Then you need to pass in your complex filter query. Note that I'm using the Year(..) function because you can't reference columns from different tables in the filter section of the Calculate (and startdate.year and enddate.year are coming from two separate date tables created automatically by powerbi).
Finally you need to wrap that into a KEEPFILTERS statement to ensure that only the current row context is being applied to the expression.
I have a table which looks like this:
I need to calculate sum of all numbers in column :ADD , IF the number in column CHANGE is 0 AND column DELETE is 0.
The actual data looks like below. Its same as above. The items with red backets should be filtered out because there are values against delete and change for each unique number in MEMO column.
Create a Measure as below to Exclude records from the list-
exclude =
VAR current_row_tsframe_account = MIN(your_table_name[TSframe_Account])
VAR current_row_tsframe_memo = MIN(your_table_name[TSframe_Memo])
VAR find_delete_change_for_memo =
CALCULATE(
COUNT(your_table_name[TSframe_Memo]),
FILTER(
ALL(your_table_name),
your_table_name[TSframe_Memo] = current_row_tsframe_memo
&& your_table_name[TSframe_Account] = current_row_tsframe_account
&& your_table_name[TSframe_Mode] IN {"CHANGE","DELETE"}
)
)
RETURN
IF(
find_delete_change_for_memo > 0,
"Yes",
"No"
)
The above Measure will return Yes/No per row. You can now Apply visual/page level filter so that records only show where measure Exclude = No. Now this below measure will show your expected value-
total = SUM(your_table_name[TSframe_Memo])
How to create a table with a specified column name and no rows at all. The following oneliner does what I want but shows error message that there should be second argument in ROW function.
EmptyTable = ROW ("Product")
I would like to use it for making bridge tables with desired column name. For example I want Product_bridge table to have a column "Product".
Product_bridge = DISTINCT(
UNION(
DISTINCT( Sales[Prod_Name] )
,DISTINCT( Dictionary[Prod_DifferntName])
,DISTINCT( PriceList[P] )
))
The code above gets me the name of the first table, in this case Prod_Name.
You could just filter it. Or select TOPN 0.
TOPN:
Table = TOPN(0;DATATABLE("Product";STRING;{{}}))
FILTER:
Table = FILTER(DATATABLE("Product";STRING;{{}});0)
This is how I create empty DAX tables:
EmptyTable = DATATABLE (
"Other Measures", INTEGER,
{
{ 0 }
}
)
I would like to add to mxix answer a few useful oneliners for making one-column empty table with desired name:
OneLiner1 = TOPN(0, ROW("Product", "Apple"))
OneLiner2 = FILTER(ROW("Product", "Apple"), 1=2)
Or if you want to define column type:
OneLiner3 = TOPN(0, DATATABLE("Product", STRING,{{"Apple"}}) )
So the snipped for bridge table is:
Product_bridge = DISTINCT(
UNION(
TOPN(0, ROW("Product", "Apple"))
,DISTINCT( Sales[Prod_Name] )
,DISTINCT( Dictionary[Prod_DifferntName])
,DISTINCT( PriceList[P] )
))
Select col1,'EOI' as col4,col2 from (
Select 'EOI' as col1,count(drmca_epcsubcontdtls_fk) as col2 from drmaincontanalytics_tbl where drmca_l1evnttype=1
union
select 'EOI' as col1,count( drsubcontanalytics_pk) as col2 from drsubcontanalytics_tbl where drsca_l2evnttyp=1
)
I need to implement this query in dax
I tried this measure but i cannot figure out how to take union in x1 and x2
MEOI_TENDSTATUS =
VAR X1 =
CALCULATE (
DISTINCTCOUNT ( drmaincontanalytics_tbl[drmca_epcsubcontdtls_fk] ),
drmaincontanalytics_tbl[drmca_l1evnttype] = 1,
drmaincontanalytics_tbl[drmca_tendstatus] = 5
)
VAR X2 =
CALCULATE (
DISTINCTCOUNT ( drsubcontanalytics_tbl[drsca_epcsubcontdtls_fk] ),
drsubcontanalytics_tbl[drsca_l2evnttyp] = 1,
drsubcontanalytics_tbl[drsca_tendstatus] = 5
)
RETURN
X1 + X2
Creating your table variables, X1 and X2
DISTINCTCOUNT() returns a number, so your X1 and X2 variables are numbers, hence your X1 + X2 calculation is just going to give you the sum.
You can use FILTER() to return a table, for example:
VAR X1 = FILTER(drmaincontanalytics_tbl, drmaincontanalytics_tbl[drmca_l1evnttype] = 1)
This will return the entire table with the applied filters. If you want to return a one column table, you can wrap this in a SELECTCOLUMNS() function.
Appending the table variables with UNION()
There's a UNION() function in DAX which you can use to replicate the SQL equivalent. It takes table functions as arguments. Once you've defined your table variables properly, you'll be able to append them like this:
VAR X1 = SELECTCOLUMNS(FILTER())
VAR X2 = SELECTCOLUMNS(FILTER())
RETURN
UNION(X1, X2)
Finally, if you're trying to return a table which you can use in your data model, make sure you're creating this via the "New Table" option, not "New Column" or "New Measure".
Alternatively, you can write SQL directly in your source in query view if you navigate to 'Advanced Options' for the 'Source' step.