In DAX, the PATH function requires parameters which are column references. In the example below, I can use a PATH function referring to the "ID" and "ParentID" columns which are statically defined in the DEFINE statement.
DEFINE
TABLE MyTable = UNION (
ROW ( "ID", 1, "ParentID", BLANK ( ) ),
ROW ( "ID", 2, "ParentID", 1 ),
ROW ( "ID", 3, "ParentID", 1 ),
ROW ( "ID", 4, "ParentID", 2 )
)
EVALUATE
ADDCOLUMNS (
MyTable,
"Path", PATH ( MyTable[ID], MyTable[ParentID] )
)
-- Result
-- ID ParentID Path
-- 1 BLANK 1
-- 2 1 1|2
-- 3 1 1|3
-- 4 2 1|2|4
My question is how I can refer to columns created dynamically in a table variable? With the below query, I get an error saying that the MyTableVar is not found.
EVALUATE
VAR MyTableVar = UNION (
ROW ( "ID", 1, "ParentID", BLANK ( ) ),
ROW ( "ID", 2, "ParentID", 1 ),
ROW ( "ID", 3, "ParentID", 1 ),
ROW ( "ID", 4, "ParentID", 2 )
)
RETURN ADDCOLUMNS (
MyTableVar,
"Path", PATH ( MyTableVar[ID], MyTableVar[ParentID] ) -- Error: MyTableVar is not found
)
I also tried PATH ( [ID], [ParentID] ), but the error message says [ID] is not a valid reference to a table column.
I researched several articles but could not find a solution.
Microsoft Docs - PATH
DAX GUIDE - PATH
Microsoft Docs - Column and measure references
SQLBI - Table and column references using DAX variables
Microsoft Power BI Community Forum - DAX: Is it possible to refer to columns of a table variable?
Related
In Power BI, I have a table based on UNION of 2 different tables:
ResultTable =
UNION (
SELECTCOLUMNS (
'Table1',
"Name", 'Table1'[name] ,
"Number", 'Table1'[number]
) ,
SELECTCOLUMNS (
'Table2',
"Name", 'Table2'[name] ,
"Number", 'Table2'[number]
)
)
Here is the ResultTable output:
Name
Number
A
1
A
2
A
3
A
1
A
2
C
5
A
3
B
4
Can I get distinct rows based on the Number column so that it becomes:
Name
Number
A
1
A
2
A
3
C
5
B
4
Note that you have to specify an aggregation in case there are different names for a single number. This is not the case with your sample data, so either MIN() or MAX() will work. Use this expression as a calculated table:
Distinct Numbers =
SUMMARIZE(
ResultTable,
ResultTable[Number],
"Name", MIN(ResultTable[Name])
)
Your desired output still describes a simple distinct on the entire UNION result, so just wrap it in DISTINCT:
ResultTable =
DISTINCT (
UNION (
SELECTCOLUMNS (
'Table1',
"Name", 'Table1'[name] ,
"Number", 'Table1'[number]
) ,
SELECTCOLUMNS (
'Table2',
"Name", 'Table2'[name] ,
"Number", 'Table2'[number]
)
)
)
Did you mean to do a group by NUMBER, while implementing some logic for picking the right NAME out of aggregation?
I am looking for a DAX measure to solve the following problem:
Count the number of rows in the dimension table where the Fact table either has no rows or the score is 0.
Table A (Dimension Table)
ID
name
1
a
2
b
3
c
Table B (Fact Table)
ID
score
1
0
1
1
1
2
2
5
Expected Result
In this example, I would expect 2, as ID=1 has one row with score=0 and ID=3 as no corresponding row in the Fact Table.
I came up with this measure which gives me the number of rows that have no corresponding row in the fact table, but I am not able to integrate the first condition:
CALCULATE(COUNTROWS('Dimension'), FILTER ('Dimension', ISBLANK ( CALCULATE ( COUNT ('Fact'[id]) ) )))
Probably much more straightforward methods, but try this measure for now:
MyMeasure =
VAR MyTable =
ADDCOLUMNS(
Table_A,
"Not in Table_B", NOT (
Table_A[ID]
IN DISTINCT( Table_B[ID] )
),
"Zero Score in Table_B",
CALCULATE(
COUNTROWS( Table_B ),
Table_B[score] = 0
) > 0
)
RETURN
SUMX(
MyTable,
[Not in Table_B] + [Zero Score in Table_B]
)
You can also try this
CountID =
VAR ScoreZero =
COUNTROWS ( FILTER ( TableB, [score] = 0 ) )
VAR NonExistentIDs =
COUNTROWS ( EXCEPT ( DISTINCT ( TableA[ID] ), DISTINCT ( TableB[ID] ) ) )
RETURN
ScoreZero + NonExistentIDs
This also works, not sure it's a good idea to nest CALCULATE:
CALCULATE(COUNTROWS('Table_A'), FILTER ('Table_A', ISBLANK ( CALCULATE ( COUNT ('Table_B '[id]) ) ) || CALCULATE(COUNTAX(Filter('Table_B ','Table_B '[score]=0),'Table_B '[id])>=1)))
I have a table with multiple date columns, and a single label column, as shown by following code
Data = DATATABLE (
"Date1", DATETIME,
"Date2", DATETIME,
"Label", STRING,
{
{ "2020-01-01","2020-01-02", "A" },
{ "2020-01-01","2020-01-01", "A" },
{ "2020-01-01","2020-01-02", "B" },
{ "2020-01-01","2020-01-01", "D" },
{ "2020-01-01","2020-01-02", "E" },
{ "2020-01-02","2020-01-01", "A" },
{ "2020-01-02","2020-01-02", "B" },
{ "2020-01-02","2020-01-01", "C" }
}
)
I want to plot a chart of count of distinct labels for each day, when considering date1, as well as when considering date2. These need to be in same plot, as a clustered bar plot, as shown below. This means I need to get the values on a new date column.
The expected result looks like this,
Date | value1 | value2
---------------------------------
1/1/2020 12:00:00 AM | 4 | 3 |
1/2/2020 12:00:00 AM | 3 | 3 |
Current Solution:
I am creating two different tables for each of the counts, as follows
Date1_Count =
ADDCOLUMNS (
ALL ( Data[Date1] ),
"Count",
CALCULATE (
DISTINCTCOUNT ( Data[Label] )
)
)
and
Date2_Count =
ADDCOLUMNS (
ALL ( Data[Date2] ),
"Count",
CALCULATE (
DISTINCTCOUNT ( Data[Label] )
)
)
Then I create a third table with dates as such,
Final_Counts = CALENDAR("2020-01-01", "2020-01-04")
Next, I add relationship between the three dates, viz. Date1_Count table, Date2_Count table, and Final_Counts table
Finally, I combine the data using RELATED function as follows
value1 = RELATED(Date1_Count[Count])
value2 = RELATED(Date2_Count[Count])
Question
Is there a simpler solution that does not require creating one table per date column? The current method is not scalable to many date columns.
Assuming you only have a handful of date columns, you just need a single date dimension table and one measure per date column.
Define a date table to use on the x-axis (no relationships to other tables):
DimDate = CALENDAR("2020-01-01", "2020-01-04")
Then define measures that match the various date columns to the date table:
value1 =
CALCULATE (
DISTINCTCOUNT ( Data[Label] ),
Data[Date1] IN VALUES ( DimDate[Date] )
)
and
value2 =
CALCULATE (
DISTINCTCOUNT ( Data[Label] ),
Data[Date2] IN VALUES ( DimDate[Date] )
)
If you have more than a handful of DateN columns, then you'd probably be best served to reshape your data where you unpivot all those columns.
For just the two you have the data would look like
In this case, you use Unpivot[Column] as the Legend and only need a single measure:
value =
CALCULATE (
DISTINCTCOUNT ( Unpivot[Label] ),
Unpivot[Date] IN VALUES ( DimDate[Date] )
)
This gives a similar looking result:
It is possible to obtain the Final_Counts calculated table in one step, using ADDCOLUMNS to iterate over Data[Date1], and then calculating Value1 as the DISTINCTCOUNT over the Data table filtered on the currently iterated Date1.
This work thanks to the CALCULATE statement that triggers a context transition.
Obtaining the Value2 requires to create a new filter context over Date2 using the currently iterated Date1.
First we save the current Date1 in a variable to be used inside CALCULATE in the filter expression on Date2.
We also need REMOVEFILTERS( Data ) to remove the filter context over Date1 set by the context transition.
Final_Counts =
ADDCOLUMNS(
ALL( Data[Date1] ),
"Value1",
CALCULATE(
DISTINCTCOUNT( Data[Label] )
),
"Value2",
VAR CurrentDate = Data[Date1]
RETURN
CALCULATE(
DISTINCTCOUNT( Data[Label] ),
REMOVEFILTERS( Data ),
Data[Date2] = CurrentDate
)
)
The below table has 2 columns
Where Column A is a Date column and Column B is a Text column where some values are equal to "x" and some are blank.
I need to create an output column which based on the below formula
IF (
AND ( ColumnA < EOMONTH ( ColumnA, 3 ), ( ColumnB = "x" ) ),
EOMONTH ( ColumnA, 3 ),
"-"
)
I have written the following DAX formula for it:
Output =
IF (
AND (
ColumnA
< EOMONTH ( DATE ( YEAR ( ColumnA ), MONTH ( ColumnA ), DAY ( ColumnA ) ), 3 ),
( ColumnB = "x" )
),
EOMONTH ( ColumnA, 3 ),
"-"
)
I'm getting an error with this formula that NULL is not allowed in this context
Note: We can leave Blank in place of "x".
How do I write the correct DAX formula to achieve the above?
The problem with your calculation is that you are mixing different data types in the same column.
The Output column is handling a date data types with a text data types, that's why you are getting an error. The columns could only handle date or text but not both at the same time.
To fix your calculation your need to change your ELSE statement from "-" to BLANK()
I have 1 file which has the following columns: Document Date and Disposition Date.
In Power BI Desktop, I'd like to create another column called 'Duration' which can be calculated by taking Disposition Date - Document Date and I want the new column to display in number values since both the Disposition Date & Document Date are either in serial number (ex: 39448) or date (ex: 09/25/2018) format.
Is there a code or something to do this? Thank you!
I may be missing the point here, but if you have a dataset such as this:
Document Disposition
25.09.2018 22.09.2018
24.09.2018 21.09.2018
23.09.2018 20.09.2018
22.09.2018 19.09.2018
21.09.2018 18.09.2018
20.09.2018 17.09.2018
19.09.2018 16.09.2018
18.09.2018 14.09.2018
17.09.2018 13.09.2018
16.09.2018 12.09.2018
15.09.2018 11.09.2018
14.09.2018 10.09.2018
13.09.2018 09.09.2018
12.09.2018 08.09.2018
11.09.2018 07.09.2018
10.09.2018 06.09.2018
09.09.2018 05.09.2018
08.09.2018 04.09.2018
Then you can load them using Get Data, go to Edit Queries, select Add Column, and simply set it up like this:
Then you can click the ABC / 123 icon on top of the column and change the datatype to Whole number, and you'll get this:
Please let me know if this is not what you were looking for.
First create two new date columns for document and disposition since there are some variances in datatype. I am basically just checking if after conversion, there is a "/" in the date field implying it is a date type, if not I am assuming it is serialized and will convert. The following DAX should do it BUT it is not tested, so try it out.
True Document Date :=
SWITCH (
TRUE (),
AND (
ISERROR ( SEARCH ( "/", FORMAT ( [Document], "text" ) ) ),
[Document] >= 32767
), FORMAT ( DATE ( 2000, 1, [Document] - 36523 ), "YYYY-MM-DD" ),
AND (
ISERROR ( SEARCH ( "/", FORMAT ( [Document], "text" ) ) ),
[Document] < 32767
), FORMAT ( DATE ( 1900, 1, Sheet1[DATE SERIAL NUMBER] ), "YYYY-MM-DD" ),
NOT ( ISERROR ( SEARCH ( "/", FORMAT ( [Document], "text" ) ) ) ), [Document]
)
True Disposition Date :=
SWITCH (
TRUE (),
AND (
ISERROR ( SEARCH ( "/", FORMAT ( [Disposition], "text" ) ) ),
[Disposition] >= 32767
), FORMAT ( DATE ( 2000, 1, [Disposition] - 36523 ), "YYYY-MM-DD" ),
AND (
ISERROR ( SEARCH ( "/", FORMAT ( [Disposition], "text" ) ) ),
[Disposition] < 32767
), FORMAT ( DATE ( 1900, 1, Sheet1[DATE SERIAL NUMBER] ), "YYYY-MM-DD" ),
NOT ( ISERROR ( SEARCH ( "/", FORMAT ( [Disposition], "text" ) ) ) ), [Disposition]
)
Then, just take the difference in days and store results a new calculated column:
Date Delta :=
DATEDIFF ( [True Document Date], [True Disposition Date], DAY )