Building a table from an existing table - powerbi

I have a SQL query which generates a table which in turn populates a custom visual, which works as intended. However, I now want to use this table, to avoid calling another SQL script, to populate a new table.
The original SQL creates a table such as this:
Now i want to use this information in order to populate another table, which if I were using the original SQL query as the starting point, I would write:
SELECT
2 AS 'Level',
'Warning' AS 'Text',
[Heading] AS 'Department'
FROM
#t
WHERE
[Inventory Days] > 4
UNION ALL
SELECT
1,
'CodeRedAlert',
[Heading]
FROM
#t
WHERE
[Capacity Warning] > 3
Which would output the following:
Level Text Department
2 Warning Section 1
2 Warning Section 2
2 Warning Section 3
1 CodeRedAlert Section 2
Which could be then used to populate the table visual within Power BI which would have icons for the warnings and code red alert.
Whilst this is achievable within SQL, considering I have the data in a table within Power BI, is there a way of building this new table within the confines of Power BI using DAX?
Cheers for any help provided.

I think you can get to where you want to be with something like this:
Table = UNION(
SELECTCOLUMNS(
FILTER(Table1, [Inventory Days] > 4)
, "Level", 2
, "Text", "Warning"
, "Department", 'Table1'[Heading]
)
, SELECTCOLUMNS(
FILTER(Table1, [Inventory Days] > 3)
, "Level", 1
, "Text", "CodeRedAlert"
, "Department", 'Table1'[Heading]
)
)
This is using the SelectColumns function to pull data out of the original table and set the constant fields. I've replaced the 'where' clause from the SQL example with a Filter. Then the two different sets are stitched together with Union.
Hope it helps

Related

Left Joining Tables in Power BI based on multiple columns with duplicate values (DAX)

I am trying to join 2 tables (left join) in Power BI using DAX, and I keep on encountering errors.
The dummy table structure and desired outcome are below:
How would I join the two tables where the Application and Business Unit should match in Both Tables and considering that Table A & B contain duplicate values?
One of the statements I have tried is below, however I keep on encountering errors regarding duplicate values and I am not sure how to proceed. I can't use Power Query unfortunately, this has to be in DAX.
TABLE =
GENERATEALL (
Table_A,
CALCULATETABLE (
ROW (
"New vs Old", VALUES (Table_B[New vs Old]),
"Project", VALUES (Table_B[Project])
),
TREATAS ( ROW ( "Business Unit", Table_A[Business Unit] ), Table_B[Business Unit] ),
TREATAS ( ROW ( "Application", Table_A[Application] ), Table_B[Application] )
)
)
Thank you
Use NATURALLEFTOUTERJOIN Like this:
Table =
var TABLE_A = SELECTCOLUMNS(
{
("A","BU1","2022-10",100),
("B","BU2","2022-11",200),
("B","BU3","2022-10",100),
("C","BU1","2022-11",400),
("D","BU2","2022-12",50)
},"Application",[Value1],"Business Unit",[Value2], "Month",[Value3], "Cost",[Value4])
var TABLE_B = SELECTCOLUMNS(
{
("A","BU1","Project 1","New"),
("B","BU2","Project 2","New"),
("B","BU2","Project 5","Old"),
("B","BU3","Project 3","Old"),
("C","BU1","Project 1","Old"),
("D","BU2","Project 4","New")
},"Application",[Value1],"Business Unit",[Value2], "Project",[Value3], "New vs Old",[Value4])
return NATURALLEFTOUTERJOIN(TABLE_A,TABLE_B)
If your column names or data types don't match you'll need to CONVERT and rename them before joining.
You need to create a Calculated Column that introduces a Union between "Applications" and "Business Unit", in both tables, then introduce tge relationship with this column created. It’s like creating a Primary Key.

Power BI - Need a slicer to look at multiple columns of Data

I am learning PowerBI as i go along and have been able to solve most issues faced by a quick google. Unfortunately this problem has baffled me.
We have thousands of lines of data which include a "Home Country" column & "Away Country" column.
What we need our slicer to do is to is to pick up for example Australia in both of these columns and display the results.
I currently have a table created using the below:
slicercountrytable = distinct(
Union(
Values('All Data'[Home Country]),
Values('All Data'[Away Country])))'''
and then a measure:
Measure =
if(
Min('All Data'[Home Country]) in values (slicercountrytable[Country])
|| Min('All Data'[Away Country]) in values (slicercountrytable[Country]),
1,
Blank()
)
And have also tried the below measure:
Measure 3 = VAR
Searchvalue=search(SELECTEDVALUE(slicercountrytable[Country]),SELECTEDVALUE('All Data'[Combined Country]),,Blank())
Return
If(Searchvalue > 0,"Found")
I need the slicer to control the entire sheet however the above are doing nothing.
Thanks
In that case, instead of building some complicated DAX I suggest to work the model.
Let's say your current table looks like that:
id
home country
away country
1
A
B
2
B
C
You may want to deal with that in another table by unpivoting home_country and away_country in PowerQuery.
In order to have a country table like that:
id
country
attribute
1
A
home
1
B
away
2
B
home
2
C
away
Then you link this new table to your existing one on id and filter/slice in it.
I reproduced your example and feel that it is already showing the desired behavior. I think the problem you might be running into is that you will now need to add your 'measure' filter to each and every visual individually. It cannot be added to 'Page' or 'All Pages' filter areas. This is because of the way a measure's calculation varies across context and cannot be avoided.
DAX
Table 2 = distinct(union(all('Table'[Away]), all('Table'[Home])))
Measure =
if(
MAX('Table'[Away]) in VALUES('Table 2'[SelectedCountries])
|| MAX('Table'[Home]) in VALUES('Table 2'[SelectedCountries]) ,
1,
blank()
)

Microsoft Power BI DAX - Convert a table with a range of integer values in two columns, into a new table with a row for each value in the range

I have a situation in which I am using Microsoft Power BI. I have a source table (called Couriers), with a range of weights (MinWeight to MaxWeight) for any given combination of Courier and Country, along with the Freight value.
I need to develop a new TABLE (called Couriers_FlattenedData) in Power BI , in which, I get a row for each value between the MinWeight and MaxWeight.
For example, if the minimum weight to maximum weight reads as 0 and 5 for FedEx Australia, I need 5 rows from 1 to 5.
I need these 4 columns in the new Couriers_FlattenedData table - Courier, Country, Weight, Freight. The Weight column is converted to rows based on the range in the source table.
I am trying to derive the new table, in both DAX as well as using the backend Power Query Editor (using M language). I would like to get both ways to develop this new table.
I tried something like this in DAX, but not able to get a solution.
Couriers_FlattenedData = SELECTCOLUMNS (
GENERATE (
'Couriers', GENERATESERIES (
CALCULATE(DISTINCT(Couriers[MinWeight])+1),
CALCULATE(DISTINCT(Couriers[MaxWeight]))
)
),
"Courier", Couriers[Courier],
"Country", Couriers[Country],
"Freight", Couriers[Freight]
)
Can someone correct the above DAX expression, which misses the Weight column ? Or even provide a solution using variables?
And also a step by step solution using the Power Query Editor of Power BI ?
DAX Solution:
Couriers_FlattenedData = SELECTCOLUMNS (
GENERATE (
Couriers,
GENERATESERIES(Couriers[MinWeight] + 1, Couriers[MaxWeight])
),
"Courier", Couriers[Courier],
"Country", Couriers[Country],
"Weight", [Value],
"Freight", Couriers[Freight]
)
Query Editor solution:
Duplicate the Couriers table (in the Query Editor), then go to Advanced Editor of the Query Editor, then paste this:
let
Source = Couriers,
WeightList = Table.CombineColumns(Source,{"MinWeight", "MaxWeight"},each {_{0}+1.._{1}},"Weight"),
ExpandWeightList = Table.ExpandListColumn(WeightList, "Weight"),
ChangedType = Table.TransformColumnTypes(ExpandWeightList,{{"Weight", Int64.Type}})
in
ChangedType
Rename the table as Couriers_FlattenedData

RANKX without creating a summary table

I'm a newbie in DAX and I'm trying to create a visual in Power BI that shows the top 10 customers by sales.
I tried to create a calculated column in the 'Food sales' table, but I couldn't figure out how to create the rank by client ID.
I ended up creating a summary table in the model:
Consolidation Ventes =
SUMMARIZE('Food Sales',
'Food Sales'[ID Client],
"Ventes",SUMX('Food Sales', 'Food Sales'[Quantité]*'Food Sales'[Prix de vente])
)
and adding the rank calculated column like that:
Rank = RANKX('Consolidation Ventes', 'Consolidation Ventes'[Ventes],,DESC,Dense)
I obtained what I was looking for:
But I'm pretty sure there's a better way to do it, without creating an extra table in the model.
I tried creating a measure instead, but it always returned "1" and I couldn't understand why...
Is there a better way to achieve the same result?
Is there a way to create a measure instead of a calculated column, to create dynamic ranks in order to slice the with more than one column (like for example, customer name and product type)?
I hope this helps:
#Orders := COUNTROWS(Sales)
SalesAmount := SUMX(Sales,Sales[Quantity]*Sales[Price])
TopN :=
COUNTROWS(INTERSECT(
CALCULATETABLE(
TOPN(5,VALUES(Customers[Name]),[SalesAmount],DESC),
ALL(Customers)
),
CALCULATETABLE(VALUES(Customers[Name]))
))
You add the TopN measure to "Filters on this visual" and define the filter condition to "TopN is 1".

Power BI - count active items between two dates

I have a query I tried to resolve but I failed badly.
I have a table with items and want to count active ones per day. I did it in excel where I created another column with the last 7 days and I used countifs.
So my excel formula is
=COUNTIFS($A$3:$A$30001,"<="&F3,$B$3:$B$30001,">="&F3)
But I need the same in Power BI.
My table with data is called ADW_DEFECTS and has two columns with open and closed dates.
ISSUE_DTTM CLOSE_DTTM
26/11/2019
26/11/2019
26/11/2019
26/11/2019
26/11/2019
25/11/2019
25/11/2019
25/11/2019
24/11/2019 25/11/2019
24/11/2019 25/11/2019
24/11/2019 25/11/2019
24/11/2019 26/11/2019
23/11/2019 24/11/2019
23/11/2019 24/11/2019
23/11/2019 25/11/2019
22/11/2019 22/11/2019
Now I figure out I need to pivot to another table for the last seven days' calculations (I used a table called NEW.DEFECTS_ACTIVE).
This is the result of excel
Dates Active
26/11/2019 1
25/11/2019 5
24/11/2019 7
23/11/2019 3
22/11/2019 1
21/11/2019 0
20/11/2019 0
So, the required result in Power BI is a table with the same as excel one.
You can also expand the table like this, though you end up with a second table:
Expanded_ADW =
GENERATE(
CALCULATETABLE(
ADW_DEFECTS;
ADW_DEFECTS[CLOSE_DTTM] <> BLANK()
);
SELECTCOLUMNS(
GENERATESERIES(
ADW_DEFECTS[ISSUE_DTTM];
ADW_DEFECTS[CLOSE_DTTM]
);
"Expanded_Date"; [Value]
)
)
Then have a calendar with a 1:* relationship with [Expanded_Date]. In a visual table with date from the Calendar tabel add this measure:
Active = COUNTROWS('Expanded_ADW')+0
Then you have a table like this:
First I would create a Dates table. There are many ways to do this - for more complex requirements I prefer Power Query but for a simple demo you can go to the Modeling ribbon, choose New table and enter:
Dates = CALENDARAUTO(1)
Next review the Model view and make sure there are no relationships between the new Dates table and your existing ADW_DEFECTS table.
Then I would go to the Modeling ribbon and choose New measure, and copy in this DAX formula:
Active =
SUMX (
Dates,
CALCULATE (
COUNTROWS ( ADW_DEFECTS ),
FILTER (
ADW_DEFECTS,
[Date] >= ADW_DEFECTS[ISSUE_DTTM]
&& [Date] <= ADW_DEFECTS[CLOSE_DTTM]
)
)
)
This basically says for each row in Dates, count how many rows from ADW_DEFECTS are "Active". You have to imagine the Measure formula running in every cell of your output visual. The outer SUMX will calculate a total for all Dates by summing the Date-level results - e.g. how many "Days Active".
Finally add a Table visual to the Report view. Add the Date column from the Dates table and the Active measure. Turn off the Totals if you don't want to show that.
It doesn't produce the extra rows with zeros, e.g. 20/11/2019, but they seem arbitrary. If they are actually required, just add + 0 to the measure formula and filter the Date column on the Table visual.