Using the SELECTEDVALUE function in DAX

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
- Ciao friends. In this video I want to introduce the SELECTEDVALUE function in DAX and show you a couple of examples where it proves to be useful. SELECTEDVALUE is a useful and powerful function, and once you learn how and when to use it you will find a lot of different scenario where it makes a lot of sense to use it. But as with all the DAX function, you need to understand exactly what it does in order to use it properly. Let's start by looking immediately at the scenario where SELECTEDVALUE is useful. Look at this report. I'm showing the product name, the sales amount and the product class all in the same report. Now, this visual is currently a table. Being a table I can put columns coming from the product table, like I did here, I put the class and the product name, anywhere in the report. So the product class is here beside the sales amount. What if I want to transform this table into a matrix? I can do that. I just go there and transform that into a matrix. Now, the product class went on the columns. I don't want there, I want it on the rows. And look what happens. Now the product class is below the product name. And I don't want to see the product class below the product name, because there is always one value for the product class given a product. What I'd like to see is the product class in this area here. The thing is I cannot show columns in that area. In order to show values there what I need is a measure, therefore what I need to do is create a measure that computes the product class. And I can do that. I start by building a measure that I call product class. And I can start just writing product class. But you see where the problem is, I cannot even write product class. Intellisense does not let me create or use the product class column, so the class column in the product table. The reason is, there is no row context right now. And because there is no row context, I cannot access the values of a column. A measure is executed in a filter context where a column does not have a value. What I can do instead of retrieving the value of one row only, I can use the VALUES function and retrieve the values of product class. What I want, or what I hope, is that because there is always one product only in my visual, VALUES returns a table with one row only and the automatic conversion of a table into a scalar value will happen. Unfortunately, if I put that in the report I obtain an error. And if we look at the details of the error it says that a table of multiple values was supplied where a single value was expected. Indeed, my measure worked fine for all of the rows, but it did not work here at the grand total, because row by row there is only one value for the product class, but at the grand total, there will be multiple. So what I need to do is protect my code and say well, IF HASONEVALUE product class, so if there is only one value visible in the current filter context for the product class, then compute the values of the product class. Otherwise, just return a blank. And if I use the measure now, you'll see that I obtained my result. Now the product class is among the different measures that I can use in a matrix. The only drawback here is that I'm showing the product class even when there are no sales. So I need to add a further level of protection that says, IF NOT ISEMPTY sales, then compute your result. Otherwise, as we did earlier, a blank is just fine. And now I have my nice result. The product class is shown only when there are sales, and it's time to get rid of the product class from the rows. So I now have the product name, the sales amount and the product class all in the matrix, as if they were a table. The only problem, or where SELECTEDVALUE comes in, is that writing this code all the time is kind of boring. You always need to remember to add IF HASONEVALUE and then VALUES. SELECTEDVALUE does exactly what the code from row four to row seven does. I can replace these with SELECTEDVALUE of product class. Now the code is shorter. I can just hit Enter, and as you see, nothing changes in the result. SELECTEDVALUE does exactly what my IF HASONEVALUE code did earlier. Not only, SELECTEDVALUE also provides me a default value. In case there are multiple values, I can use whatever other value as a default. And as soon as I hit Enter, you see that this string will appear here at the grand total, where there are multiple values for the product class. As you see, you can control what happens row-by-row, and also what happens at the total level. Now, for the product class, let's get rid of those asterisks, which are not that meaningful at all. Now I have the product class. I can use SELECTEDVALUE the same way to obtain not only the product class but a product category. Let's look at where the product category is. In this specific model I have a snowflake. So I have sales that goes to product, and product has a relationship with subcategory, and finally with category. So product category appears here. And I'm slicing by the product name, which is here. So the filter starts from product, and I want to access the product category. What happens if I use, in the same way, SELECTEDVALUE? I can create a new measure, let's call it product category, that checks IF NOT ISEMPTY sales. And we take the SELECTEDVALUE of product category. Now I have my measure, I can put it in the report, and it always shows a blank. Why that? Well, the answer is here. The filter starts from product, but this relationship is many-to-one, and then many-to-one. This tiny arrow is showing the direction of the filter context, and it shows that the filter context goes from the one to the many side, not from the many to the one side. I could make this relationship bi-directional, but that would be bad, you know, bi-directional relationships are dangerous. So another option, which is what I'm going to do here, is to use a bi-directional relationship, but activate them only for the duration of my calculation. So I can use CALCULATE SELECTEDVALUE. And then I use CROSSFILTER to move the relationship between sales subcategory key. No, sales product key. Actually, no sales between product subcategory key. I need more space. And product subcategory, subcategory key, we make this relationship bi-directional. And then we need to do the same for the relationship between subcategories and categories. So we also use CROSSFILTER between... between category key and subcategory, and the category key in category, product category key. Oh, here. These need to be bi-directional too. Now my code is much longer, but I need to author it this way if I want to access a column which is on the one side. I can now hit Enter, and if I did everything correctly, you now see that I have my product category visible here. So again, SELECTEDVALUE is useful. You only need to pay attention to make sure that there will be only one value visible in the current filter context on the table where you want to grab the value. I want to show you another example where SELECTEDVALUE proves useful. And it is when you have reports with sales amounts, like in this case, but you want to use a slicer to control the scale of this number. So right now I'm showing the value as it is. But what I would like to see is, show the value divided by 1,000 or 1 million, and that is extremely useful when the values become very large and you want to reduce their size in order to make them more readable for users. So I have a slicer here. I have my sales amount that is not going to change, but the sales by scale measure is going to change and reflect the selection that I made with the slicer. You see that if I use a thousand, this number becomes smaller, and if I use a million, this number become even smaller, so they're easier to confront and to compare. How does sales by scale work? Well, sales by scale uses, again, SELECTEDVALUE. It uses SELECTEDVALUE from the scale table. Scale is a table that is used in the slicer, it's just a table containing one, 1,000 and 1 million. When I place a filter with the slicer, that filter reduces the number of rows visible on the scale table, and SELECTEDVALUE returns a value only when there is actually one value. By default, I'm taking one, meaning that if I do not make any selection, my sales by scale show the same value as sales amount. And the same happens if I do multiple selection, because SELECTEDVALUE returns the default value when either there are no values visible or there are too many values visible. If I want to produce an error when there are multiple values visible, or when there are no selection, I can change my sales by scale, and, for example, I can throw an error, that says, "Select only one scale". If I now hit, I'm missing a parenthesis. If I now hit Enter, because there is no selection, it's likely the model returns an error. Indeed, you see that if I look at the details, it says, "There was a calculation error. "Select only one scale." And when you select only one scale, now the number becomes the right one. Returning an error or choosing a default value, well, that depends specifically on the calculation that you want to do. But as you have seen, you can use SELECTEDVALUE to read values from slicers and use those values inside your formulas in order to change the behavior of your formulas and of your code. Now, as you have seen, SELECTEDVALUE is a simple and powerful function. You can use it in a lot of different scenarios. If you are interested in looking at more scenarios about SELECTEDVALUE, make sure to go to SQLBI.com. There you will find the article that shows multiple examples and a more complete description of the code. And you will also be able to download the file in order to try by yourself, play with DAX and learn more about the SELECTEDVALUE function. Enjoy DAX.
Info
Channel: SQLBI
Views: 135,986
Rating: undefined out of 5
Keywords: DAX, PowerBI, Power BI, C0070, CONT, Alberto Ferrari
Id: Zhp1fAfN8Hw
Channel Id: undefined
Length: 12min 27sec (747 seconds)
Published: Thu Dec 10 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.