Exclude one dimension from total count / sum in qlik - qlikview

I want to have the %-Share of a value in Qlik. I have two dimension and on KPI which I am using in a distribution graph:
The data is:
Point Brand Business
A AA 1
B AA 1
C AA 1
Right now i am using the formula: Count([Business])/Count(total [Business]), on my Y-Achse I have the Brand and my point is Point, Right now he is calculating the Super total, but How can I only calculate the total for the Brand? Something like Count([Business])/Count(total [Business], if Brand == Brand)

You should add Brand field as aggregation scope
count([Business]) / Count(total <Brand> [Business])
From Qlik's documentation
By using TOTAL [], where the TOTAL qualifier is followed by a list of one or more field names as a subset of the chart dimension variables, you create a subset of the total possible values.
Adding the field to the total can be translated as: count all Business but aggregated by Brand. And since Brand is also a dimension to the chart then for each row Count Total will be the count for the current Brand value

Related

How to calculate dynamic % of grand total as a measure on Power BI?

I have the below table connected into Power BI and I am looking for ways to create a formula calculating % of grand total of the Rating column and further subtracting with targets for each rating. For example, the % of grand total for Rating 1 is 3 divided by 7 (42.86%). The most important part of the formula is the denominator which has to remain at a total level and dynamic for any filters applied to either Grade or BU columns. For example, denominator at a total level would be 7 and when filtered down to Academy BU should be 3.
Sample Data Table:
Rating Target Table:
I want the end result to look like this,
I have used the following formula to achieve this,
Measure created: % of total calc = DIVIDE(COUNT('Table'[Rating]),CALCULATE(SUM('Table'[Count]),'Table'[Rating]))
To make the above formula work I had to add an extra column and include ones in it (see below)
I want to know if there are other ways of achieving this outcome?
ALLEXCEPT will produce such result to exclude used dimensions and include mandatory filters such as date with one condition, rating, date, any dimension must be in the same table.

Counting latest instance of multiple only based on filter context

I've got a large table of events that have occurred in an inventory of vehicles, which affect whether they are in service or out of service. I would like to create a measure that would be able to count the number of vehicles in the various inventories at any point in time, based on the events in this table.
This table is pulled from a SQL database into an Excel 2016 sheet, and I'm using PowerPivot to try to come up with the DAX measure.
Here is some example data event_list:
vehicle_id event_date event event_sequence inventory
100 2018-01-01 purchase 1 in-service
101 2018-01-01 purchase 1 in-service
102 2018-02-04 purchase 1 in-service
100 2018-02-07 maintenance 2 out-of-service
101 2018-02-14 damage 2 out-of-service
101 2018-02-18 repaired 3 in-service
100 2018-03-15 repaired 3 in-service
102 2018-05-01 damage 2 out-of-service
103 2018-06-03 purchase 1 in-service
I'd like to be able to create a pivot table in Excel (or use CUBE functions, etc) to get an output table like this:
date in-service out-of-service
2018-02-04 3 0
2018-02-14 1 2
2018-03-15 3 0
2018-06-03 3 1
Essentially, I want to be able to calculate the inventory based on any date in time. The example only has a few dates, but hopefully provides enough of a picture.
I've basically come up with this so far, but it counts more vehicles than desired - I can't figure out how to only take the latest event_sequence or event_date and use that to count the inventory.
cumulative_vehicles_at_date:=CALCULATE(
COUNTA([vehicle_id]),
IF(IF(HASONEVALUE (event_list[event_date]), VALUES (event_list[event_date]))>=event_list[event_date],event_list[event_date])
)
I tried using MAX() and EARLIER() functions, but they don't seem to work.
Edit: Added the PowerBI tag as I'm now using that software to attempt to solve this as well. See comments on Alexis Olson's answer.
I think I've found a much cleaner method than I gave previously.
Let's add two columns onto the event_list table. One which counts vehicles "in-service" on that date and one which counts vehicles "out-of-service" on that date.
InService =
VAR Summary = SUMMARIZE(
FILTER(event_list,
event_list[event_date] <= EARLIER(event_list[event_date])),
event_list[vehicle_id],
"MaxSeq", MAX(event_list[event_sequence]))
VAR Filtered = FILTER(event_list,
event_list[event_sequence] =
MAXX(
FILTER(Summary,
event_list[vehicle_id] = EARLIER(event_list[vehicle_id])),
[MaxSeq]))
RETURN SUMX(Filtered, 1 * (event_list[inventory] = "in-service"))
You can create an analogous calculated column for OutOfService or you can just take the total minus the InService count.
OutOfService =
CALCULATE(
DISTINCTCOUNT(event_list[vehicle_id]),
FILTER(event_list,
event_list[event_date] <= EARLIER(event_list[event_date])))
- event_list[InService]
Now all you have to do is put event_date on the matrix visual rows section and add the InService and OutOfService columns to the values section (use Maximum or Minimum for the aggregation option rather than Sum).
Here's the logic behind the calculated column InService:
We first create a Summary table which calculates the maximal event_sequence value for each vehicle. (We filter the event_date to only consider dates up to the current one we are working with.)
Now that we know what the last event_sequence value is for each vehicle, we use that to filter the entire table down to just the rows that correspond to those vehicles and sequence values. The filter goes through the table row by row and checks to see if the sequence value matches the one we calculated in the Summary table. Note that when we filter the Summary table to just the vehicle we are currently working with, we only get a single row. I'm just using MAXX to extract the [MaxSeq] value. (It's kind of like using LOOKUPVALUE, but you can't use that on a variable.)
Now that we've filtered the table just to the most recent events for each vehicle, all we need to do is count how many of them are "in-service". I used a SUMX here where the 1*(True/False) coerces the boolean value to return 1 or 0.
This is pretty difficult. I don't have a great answer, but here's something that kind of works.
You'll create a new calculated table where you'll calculate the status for each vehicle on each date. Start with the base cross join for each vehicle and each date:
= CROSSJOIN(VALUES(event_list[vehicle_id]), VALUES(event_list[event_date]))
Then add a calculated column to find the max sequence number for each vehicle on that date.
Sequence = MAXX(
FILTER(event_list,
event_list[event_date] <= Cross[event_date] &&
event_list[vehicle_id] = Cross[vehicle_id]),
event_list[event_sequence])
Now you can lookup the inventory value for each vehicle/sequence pair with another calculated column:
Inventory = LOOKUPVALUE(
event_list[inventory],
event_list[vehicle_id], Cross[vehicle_id],
event_list[event_sequence], Cross[Sequence])
The result should look something like this:
Once you have this, you can create a matrix using this calculated table. Put the event_date on the rows and Inventory on the columns. Filter out blank inventory values in the visual level filter and put the vehicle_id in the values field, using a count or distinct count as the aggregation method (instead of the default sum).
It should look like this:

TOTAL vs Aggr in QlikView

I'm trying to understand how TOTAL and Aggr work in QlikView. Could someone please explain the difference between the two examples below, and if possible please illustrate with a SQL query?
Example1:
Max({<Field1=>} Aggr(Sum({<Field2={'Value'}, Field1=>} StuffCount), Field1))
Example2:
Max({<Field1=>} TOTAL Aggr(Sum({<Field2={'Value'}, Field1=>} StuffCount), Field1))
Not sure what you mean with and SQL query in this example. Anyway, imagine you have this list of Customers (CustomerID) and Sales (Sales):
CustomerID/ Sales
Customer1 25
Customer2 20
Customer1 10
Customer1 5
Customer1 20
Customer3 30
Customer2 30
Then you want to show it on a pivot table with dimension CustomerID and two expressions:
Max(Aggr(Sum(Sales), CustomerID)) // this will show 60 for the first customer, 50 for the second and 30 for the third one
Max(TOTAL Aggr(Sum(Sales),CustomerID)) //this will show 60 in every row of your table (which is the maximum sum of sales among all customers)
So basically AGGR creates a temporal list of whatever you put in the first function input (in this case sum(Sales)) using the dimension of the second (CustomerID). Then you can perform operations on that list (such as Max, Min, Avg...). If you write TOTAL and use the expression in a pivot table, then you 'ignore' the dimensions that might be affecting the operations.
Hope it helps
TOTAL keyword is useful in charts/pivot tables. It applies the same calculation on every datapoint in the chart/pivot, with independence of dimentions.
Therefore - if you put your expression into pivot table - 1st option may display different values per cell (if the Aggr is rellevant) when the 2nd will result in same values.
Aggr function allows making double aggregations (avg of sum, max of count etc..) on different group by bases.

Creating buckets by comparing Dimension member against Measure using MDX

I have a Product dimension with hierarchies - product_id, initial_price, product_name and Measures - units_sold, cost_per_unit, revenue_per_unit. For each product_id I need to compare initial_price against revenue_per_unit and then assign it to a bucket based on the comparison.
Consider the following example:
Input:
product_id initial_price revenue_per_unit
1 10 12
2 20 18
3 30 30
Output:
product_id bucket_name
1 Profit
2 Loss
3 Same
How can I achieve this using MDX?
WITH Member [Measures].[Bucket] AS
CASE
WHEN [Measures].[initial_price] < [Measures].[revenue_per_unit] THEN
"Profit"
WHEN [Measures].[initial_price] > [Measures].[revenue_per_unit] THEN
"Loss"
ELSE
"Same"
END
SELECT {[Measures].[Bucket]}
ON COLUMNS,
[Product].[Product Name].Members
ON ROWS
FROM [yourcube]
should deliver what you want. Please note that calculated measures need not return numbers, they also can return strings in MDX (they even can return a string for some cells, and a number for others).
In case you do not have the price available as e. g. an average price on aggregated product level, and want to do the bucketing on product level, the best solution would be not do do that in MDX at all, but in the cube design: Just calculate the bucket on the relational side, and add it as an attribute to the product dimension.
You did not state anything about other dimensions, especially time. In case some other dimensions matter as well to determine the bucket, it might be necessary to add a separate dimension just for the buckets.

sum group by in MDX

I want the equivalent SUM and Group By as in t-SQL. But I haven't found the answer on the web.
My MDX return has some records that have the same name. I want to show the distinct name with the measure summed up just like Group by feature in SQL.
It seems like it's a common feature. Thanks.
When you define a measure in AS you can set it several different ways including count and sum.
Let's assume you have a product dimension and a fact of sales. A simple query to get the total sales by product would look like the following.
SELECT {[Measures].[ItemCount], [Measures].[SalesDollars]} ON 0,
[Products].[Products].children ON 1
FROM [CUBE]
This would give you sample output like
Product Item Count Sales Dollars
Bike 10 1000
Tire 3 650