简体   繁体   中英

Power BI: How to use OR between 2 different filters?

I have some table like this:

+------+------+------+
| Lvl1 | Lvl2 | Lvl3 |
+------+------+------+
| A1   | B1   | C1   |
| A1   | B1   | C2   |
| A1   | B2   | C3   |
| A2   | B3   | C4   |
| A2   | B3   | C5   |
| A2   | B4   | C6   |
| A3   | B5   | C7   |
+------+------+------+

In which it is some thing like a hierarchy.

When user select A1, he actually selects the first 3 rows, B1, selects first 2 rows, and C1, selects only the first row.

That is A is the highest level, and C is the lowest. Note that ids from different levels are unique, since they have a special prefix, A,B,C.

The problem is when filtering in more than one level, I may have empty result set.

eg filtering on Lvl1=A1 & Lvl2=B3 (no intersection), and so will return nothing. What I need is to get the first 5 rows (Lvl1=A1 or Lvl2=B3)

const lvl1Filter: IBasicFilter = {
  $schema: "http://powerbi.com/product/schema#basic",
  target: {
    table: "Hierarchy",
    column: "Lvl1"
  },
  operator: "In",
  values: ['A1'],
  filterType: FilterType.BasicFilter
}

const lvl2Filter: IBasicFilter = {
  $schema: "http://powerbi.com/product/schema#basic",
  target: {
    table: "Hierarchy",
    column: "Lvl2"
  },
  operator: "In",
  values: ['B3'],
  filterType: FilterType.BasicFilter
}

report.setFilters([lvl1Filter, lvl2Filter]);

The problem is that the filters are independent from each other, and they will both be applied, that is with AND operation between them.

So, is there a way to send the filters with OR operation between them, or is there a way to simulate it?

PS: I tried to put all data in single column (like the following table), and it worked, but the data was very large (millions of records), and so, it was very very slow, so I need something more efficient.

All data in single column:

+--------------+
| AllHierarchy |
+--------------+
| A1           |
| A2           |
| A3           |
| B1           |
| B2           |
| B3           |
| B4           |
| B5           |
| C1           |
| C2           |
| C3           |
| C4           |
| C5           |
| C6           |
| C7           |
+--------------+

Set Filter:

const allHierarchyFilter: IBasicFilter = {
  $schema: "http://powerbi.com/product/schema#basic",
  target: {
    table: "Hierarchy",
    column: "AllHierarchy"
  },
  operator: "In",
  values: ['A1', 'B3'],
  filterType: FilterType.BasicFilter
}

report.setFilters([allHierarchyFilter]);

It isn't directly possible to make "or" filter between multiple columns in Power BI, so you were right to try to combine all values in a single column. But instead of appending all possible values by union them in one column, which will give you a long list, you can also try to combine their values "per row". For example, concatenate all values in the current row, maybe add some unique separator (it depends on your actual values, which are not shown). If all columns will have values, make it simple - create new DAX column (not a measure:):

All Levels = 'Table'[Lvl1] & "-" & 'Table'[Lvl2] & "-" & 'Table'[Lvl3]

If it is possible some of the levels to be blank, you can if you want, to handle that:

All Levels = 'Table'[Lvl1] &
    IF('Table'[Lvl2] = BLANK(); ""; "-" & 'Table'[Lvl2]) &
    IF('Table'[Lvl3] = BLANK(); ""; "-" & 'Table'[Lvl3])

Note that depending on your regional settings, you may have to replace semicolons in the above code with commas.

This will give you a new column, which will contain all values from the current row, eg A1-B2-C3 . Now you can make a filter All Levels contains A1 or All Levels contains B3 , which now is a filter on a single column and we can easily use or :

在此处输入图像描述

When embedding your JavaScript code should create advanced filter, like this:

const allLevelsFilter: IAdvancedFilter = {
  $schema: "http://powerbi.com/product/schema#advanced",
  target: {
    table: "Hierarchy",
    column: "All Levels"
  },
  logicalOperator: "Or",
  conditions: [
    {
      operator: "Contains",
      value: "A1"
    },
    {
      operator: "Contains",
      value: "B3"
    }
  ],
  filterType: FilterType.AdvancedFilter
}

report.setFilters([allLevelsFilter]);

If you need exact match (eg the above code will also return rows with A11 or B35 ), then add the separator at the start and the end of the column too (ie to get -A1-B2-C3- ) and in your JavaScript code append it before and after your search string (ie search for -A1- and -B3- ).

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM