Grouping using the same value twice - powerbi

I have the below regions
California
North Central
Northeast
South Central
South East
Southwest
West
Basically, I want to have all the below plus Non-California (with all except California) in the same field is it possible with Groups
can I use the same field twice? Is it better to use DAX?
How can I do this?
Example
California
North Central
Northeast
South Central
South East
Southwest
West
Non-California
Any help would be appreciated.
Thank you

You would need to duplicate the rows that related to the Non-California regions and assign them to a region called Non-California.
I would try first to do that in the source data query, but since I don't know what that is, I will outline also how to do it with Power Query.
In Power Query, create QueryA which is a reference to the existing query with the rows that need duplicating. Create a filter for Region <> California. Replace values in Region with Non-California.
Create another QueryB which is also a reference to the original query. Append Query A to Query B.
Uncheck the load data options on the original query and QueryA. Load QueryB only.

Your solution works I tested it with
two tables and after I did a union to the both
Data1 =
VAR _Non_California =
SUMMARIZE (
FILTER ( 'Data', 'Data'[Region] <> "California" ),
Data[Account Name], Data[Amount Currency]
"Region", "Non-California",
"Amount", CALCULATE ( SUM ( Data[Amount] ))
)
RETURN
_Non_California
Data_all = Union(
SELECTCOLUMNS(data,"Account Name", Data[Account Name],"Amount", Data[Amount],"Amount Currency", Data[Amount Currency],"Region", Data[Region]),
SELECTCOLUMNS(data1,"Account Name", Data1[Account Name],"Amount", Data1[Amount],"Amount Currency", Data1[Amount Currency],"Region", Data1[Region])
)
Thank you

Related

Setting Row level security with multiple columns in Power BI

I am trying to create a filter for target table having country code column. I want to give access to people with logged in upn either in AdditionalOwner or OwnerEmail with countrycode
AdditionalOwner has emails separated by commas, Number of emails in additionalowner column is not fixed also it may have values from OwnerEmail column. So Please help me in giving RLS in this scenario
Please find my column structure
CountryCode
AdditionalOwner
OwnerEmail
AU
test1#test.com,test2#test.com
test2#test.com
Here is the DAX I have used for Owner Email
[Country Code] = LOOKUPVALUE(
UserRoles[CountryCode],
UserRoles[OwnerEmail],UserPrincipalName())
Please help me in adding RLS for AdditionalOwner column too
You may want to try using something like OR, IF, and CONTAINSSTRING in your managed role. I've included an example for you to test below. For transparency, I did not test this but this is where I would start to solve this.
OR (
UserRoles[CountryCode] =
IF(
CONTAINSSTRING ( UserRoles[AdditionalOwner], UserPrincipalName() )
, UserRoles[CountryCode], BLANK() )
, UserRoles[CountryCode] = LOOKUPVALUE(
UserRoles[CountryCode],
UserRoles[OwnerEmail], UserPrincipalName())
)

How to filter a dimension based on RLS applied to another dimension?

Assume I have 2 dimension tables and 1 fact table.
DimUser
DimClients
DimCompany
FactSales
All the dims have a 1:M relation with filter flowing from the 1 -> M side.
Assume I have configured RLS filter on DimUser ([Username] = USERNAME()) so that the user of the report can see his own data based on email address, so user can see his own record entry in DimUser. Thus it will auto filter the FactSales also, effectively the user will be able to see only his sales.
However the user can see all clients and companies in the slicer. I want to setup filter on the DimClients and DimCompany so that the user can see only clients and conpanies for which he has made sales. How can I achieve this?
For example:
How to apply RLS to the DimClients and DimCompany so that it will filter only those ClientIds that appear in the sales table based on dynamic filter [Username] = USERNAME() applied on the DimUsers table?
The other option is to enable bidirectional filtering but this is not allowed for multiple tables.
You can create a measure that looks like this:
UserFlag =
CONTAINSSTRING (
CONCATENATEX ( FactSales, RELATED ( DimUsers[UserEmail] ), "," ),
USERNAME()
)
Create your RLS role and add this filter to each dimension.
[UserFlag] = True()
The result: If a row from a dimension is related to a fact row that is in turn related to the DimUser row whose email matches USERNAME(), then the measure returns 'True.' And so RLS is filtering only to those rows.

New Column is Doubling Value Based on Nested If Formula

I have a table that looks like this. Table Screenshot
"FY 20-21 (Budgeted)", "FY21 Approved Budget" and "Revised Budget" are columns coming from three different data sources that I appended into one table. There isn't always data in all three of these columns, so I created a new column to consolidate the data with the following formula:
FY 20-21 Budget =
if(
and(
isblank('Comprehensive Budget'[FY 20-21 (Budgeted)]),
isblank('Comprehensive Budget'[FY21 Approved Budget])
),
'Comprehensive Budget'[Revised Budget],
if(
and(
isblank('Comprehensive Budget'[FY21 Approved Budget]),
isblank('Comprehensive Budget'[Revised Budget])
),
'Comprehensive Budget'[FY 20-21 (Budgeted)],
'Comprehensive Budget'[Revised Budget]
)
)
If both Budgeted and Approved are blank, use Revised.
If not, if both Revised and Approved are blank, use Budgeted.
If not, use Revised.
But if you look on the screenshot, if NONE of the columns are blank, it gives me Revised plus Budgeted. Where is the problem in my formula?
I have added your data here and found your Measure is perfectly returning your expected data as shown in the below image-
I Guess, there are some Aggregation issue in your case. You can right click on all column in the table visual properties and select Don't Summarize from the options. This should solve your issue I hope.

Filtering other tables based on cross-highlighting a filtered measure

I want to count records in a certain condition and allow people to filter down to the relevant records, but selecting a measure value (which filters so it only counts certain rows) isn't cross-filtering others as I'd expect. Maybe ths isn't possible or maybe I'm just doing it wrong, but I'd appreciate help.
I have a single table:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45Wci4tLsnPTS1SMFTSUTJUitVBEjICChmgChljCplgajSFCMUCAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [#"Customer Name" = _t, #"Ordered Recently" = _t]),
#"Change to INT" = Table.TransformColumnTypes(Source,{{"Ordered Recently", Int64.Type}}),
#"Change to T/F" = Table.TransformColumnTypes(#"Change to INT",{{"Ordered Recently", type logical}})
in
#"Change to T/F"
The result looks like this:
Customer Name Ordered Recently
Customer 1 True
Customer 2 False
Customer 3 False
Customer 4 True
Customer 5 True
I added two measures:
Count Total = COUNTROWS(Customers)
Count Recent = CALCULATE([Count Total], filter(Customers, Customers[Ordered Recently]))
If I put both measures in a bar chart and highlight the "Count Recent" measure, I'd expect it to know to filter other visuals based on the FILTER statement present in the measure, but that doesn't happen. Selecing this value doesn't impact anything else on my page (including just a count of rows).
The goal is to allow people to select a measure that counts rows and then to see the makeup of the data in those rows (select a count of late projects and filter other visuals to describe those late projects).
Is this possible or am I doing something wrong?
EXAMPLE:
Here's what it looks like now, with nothing selected:
When I select the black bar (the "Ordered Recently" measure), nothing changes right now - but here's what I want to happen (actually achieved with a slicer off screen on the T/F field):
I understand if my measure is a SUM of an integer field, it includes every row in the calculation - even when the row value is zero - and there's no way to filter my dataset based on that. However, in this case, my measure is actually using a FILTER on the dataset so that it only counts rows with a certain criteria set - given that, it should be able to filter the requested table, and then flow that filter through the rest of my dataset (the same way it would if I selected a bar from a chart where I had used that same field as the series - exactly how it works when I do this:
PBIX file to download as an example
No, I don't believe it's possible to make a measure value cross-filter other visuals based on filters within the measure definition.
You can, however, click on i.e. row header Customer 3 and it should cross-filter the other visuals to only include that customer. Any table column you set for the rows or columns of a matrix visual should behave this way.
Here's a hacky workaround:
Create a measure that shows the right values when you use the column you want to use as a filter as the Legend or Axis (like in your last image). For example, in this case, you could do this:
Total Customers =
VAR TF = SELECTEDVALUE ( Customers[Ordered Recently] )
RETURN
COUNTROWS (
FILTER (
ALLSELECTED ( Customers ),
IF ( TF, TF, TF || Customers[Ordered Recently] )
)
)
This behaves how you want, but isn't labeled as you want. To achieve that create a calculated column with the labels you want. For example,
Label = IF(Customers[Ordered Recently], "Ordered Recently", "Total Customers")
Then take Ordered Recently off the axis and put the Label column in the Legend box to get this:
Your Filter argument is really Filter(All(Customers, Customers[Ordered Recently])
You remove all filters on the Customer Table, and then specify Ordered Recently Column as the filter.
Try
[MeasureName] =Calculate([Count Total], All(Customer), Values(Customer[Recently Ordered]), Customer[Recently Ordered] = “True”)

How to JOIN summarized data from two queries into new table in DAX Power BI

I have 2 queries:
Premium:
and Losses:
How can I simply summarize data from Premium query and LEFT JOIN it to summarized data in Losses query using DAX?
In SQL it would be like that:
declare #PremiumTable table (PolicyNumber varchar(50), Premium money)
insert into #PremiumTable values
('Pol1', 100),
('Pol1', 50),
('Pol2', 300),
('Pol3', 500),
('Pol3', 200),
('Pol4',400)
declare #LossesTable table (PolicyNumber varchar(50), Losses money)
insert into #LossesTable values ('Pol1',115),
('Pol1',25),
('Pol2',0),
('Pol3',110),
('Pol3',75)
select p.PolicyNumber,
sum(p.Premium) as Premium,
sum(l.Losses)as Losses
from #PremiumTable p
LEFT JOIN #LossesTable l on p.PolicyNumber = l.PolicyNumber
group by p.PolicyNumber
Result:
I tried using NATURALLEFTOUTERJOIN but it gives me an error:
*An incompatible join column, (''[PolicyNumber]) was detected. 'NATURALLEFTOUTERJOIN' doesn't support joins by using columns with different data types or lineage.*
MyTable =
VAR Premium =
SELECTCOLUMNS(
fact_Premium,
"PolicyNumber",fact_Premium[PolicyNumber],
"Premium", fact_Premium[Premium]
)
VAR Losses =
SELECTCOLUMNS(
fact_Losses,
"PolicyNumber", fact_Losses[PolicyNumber],
"Losses", fact_Losses[PaymentAmount]
)
VAR Result = NATURALLEFTOUTERJOIN(Premium,Losses)
RETURN Result
There are a few interdependent "bugs" or limitations around the use of variables (VAR) and NATURALLEFTOUTERJOIN which makes this a weird case to debug.
Some notable limitations are:
VAR:
Columns in table variables cannot be referenced via
TableName[ColumnName] syntax.
NATURALLEFTOUTERJOIN:
Either:
The relationship between both tables has to be defined before the
join is applied AND the names of the columns that define the
relationship need to be different.
Or:
In order to join two columns with the same name and no relationships,
it is necessary that these columns to have a data lineage.
(I'm a bit confused because the link mentioned do not have a data lineage; while official documentation said only columns from the same source table (have the same lineage) are joined on.)
Come back to this case.
SUMMARIZE should be used instead of SELECTCOLUMNS to obtain summary tables for Premium and Losses, i.e.:
Premium =
SUMMARIZE(
fact_Premium,
fact_Premium[PolicyNumber],
"Premium", SUM(fact_Premium[Premium])
)
Losses =
SUMMARIZE(
fact_Losses,
fact_Losses[PolicyNumber],
"Losses", SUM(fact_Losses[Losses])
)
When we apply NATURALLEFTOUTERJOIN to the above two tables, it'll return error No common join columns detected because of they have no relationship established.
To resolve this, we can make use of TREATAS as suggested in this blog post. But to use TREATAS, we have to reference the column names in Premium and Losses table, so we can't use VAR to declare them, but have to actually instantiate them.
To conclude, the solution would be:
Create calculate tables for Premium and Losses as mentioned above.
Use TREATAS to mimic a data lineage and join Premium table with Losses_TreatAs instead.
MyTable =
VAR Losses_TreatAs = TREATAS(Losses, Premium[PolicyNumber], Losses[Losses])
RETURN NATURALLEFTOUTERJOIN(Premium, Losses_TreatAs)
Results:
There's a sleazy hack that can successfully work around this awful limitation (what were the product designers thinking?).
If you add zeros (e.g. + 0) or concatenate an empty string (e.g. & "") to each join column within SELECTCOLUMNS, it breaks out of the data lineage straitjacket and runs the NATURALLEFTOUTERJOIN just using column names.
You can use this in a Measure to run dynamic logic (based on the query context from filters etc), not just while creating a calculated table.
Here's an tweaked version of your code:
MyTable =
VAR Premium =
SELECTCOLUMNS(
fact_Premium,
"PolicyNumber",fact_Premium[PolicyNumber] & "",
"Premium", fact_Premium[Premium]
)
VAR Losses =
SELECTCOLUMNS(
fact_Losses,
"PolicyNumber", fact_Losses[PolicyNumber] & "",
"Losses", fact_Losses[PaymentAmount]
)
VAR Result = NATURALLEFTOUTERJOIN(Premium,Losses)
RETURN Result
H/T to example #7 on this page, which shows this in code (without really explaining it).
https://www.sqlbi.com/articles/from-sql-to-dax-joining-tables/#code7
Hello I suggest you this way:
in PowerQuery, built up a table with policyNumber like that:
Duplicate Premium table, and remove the premium column on the duplicate. Call it PremiumPol
Duplicate the Losses table, and remove the losses column on duplicate. Call it LossesPol
Then use the button Append Query, to Append PremiumPol and LossesPol. Call it policynumber
Last remove duplicate from the appended tables
Then click on close and Apply
Check that your model is like that:
Then, to add losses and premium on a policy base is trivial, go on and select a table visual and these fields:
the result is like this:
Hope that helps!