Power BI Matrix sum totalling %ages incorrectly - sql

I have a measure in PowerBI that looks like:
Measure 2 = IF(HASONEVALUE('CPP'[KPI Group]),
SUMX('CPP',
DIVIDE(1,'Corporate Planning Project'[Full Year
Budget],0)*'CPP'[Actual Y.T.D]
),
""
)
Basically my matrix looks like:
---- KPI Group ----ActualYTD ----FullYearBudget ----Measure2
A ----$29,666,609 ----$95,540,594 ----1804%
B ---- $2,297,809 ---- $20,153,995 ---- 503%
Once you drilldown into group A, the matrix looks like:
KPI Group ---- ActualYTD---- FullYearBudget---- Measure2
A>
----1415----$1,252,548----$322,180----388.77%
----2223----$821,236----$830,860----98.84%
etc, so you can see that at the drilled down level the Measure2 calculates correctly, it is only at the highest level that the Measure2 is being summed, and so the sum of ALL of the %ages added together comes to 1804%, instead of the measure calculating at that level too, which would sum of fullyear budgets divided by sum of ActualYTD as a percentage.
Can anyone help please?
Thankyou

It seems like the purpose of your Measure2 is to show [Actual Y.T.D] as a percentage of [Full Year Budget], and to only show that if you are in the context of a single [KPI group].
The reason you aren't getting the result you expect is probably because you are using SUMX() where you shouldn't, SUMX() will calculate the percentage once for each row of the 'CPP' table and then add all of those together.
Try the following measure:
Measure 2 =
IF(
HASONEVALUE(CPP[KPI Group]),
DIVIDE(
SUM(CPP[Actual Y.T.D]),
SUM('Corporate Planning Project'[Full Year Budget]),
0
)
)

Related

Condition to SUM previous values - SQLite

My following SQLite database:
Explaining brazilian tax income:
a) if I have loss, I don't need to pay any tax (e.g.: January)
b) negative results can be subtracted from the next month positive outcome (e.g.: in February, instead of paying the full tax for $ 5942, the tax can be applied only to (5942 - 3200) = 2742.
c) if previous negative results are not sufficient to cover the next positive outcome, I got pay tax (e.g.: in September, I could compensate from June and July, but I had to aggregate from August (e.g.: total tax = -5000 -2185 +5000 +3000 = 815)
My goal would be build the following table:
I couldn't figure out a way to solve this problem. Any help?
Tks
You need to use recursive CTEs here. If you are not familiar with this feature you might check out my tutorial, the official documentation referenced in that tutorial, as well as any number of other tutorials available on the Internet.
First, I generate temporary row numbers using the row_number Window function in the source CTE block below (replace "RESULTS" with your table name).
Then I use recursive CTE (losses) to calculate residual loss from the previous months, which can be used to reduce your taxes. (This part might be tricky to understand if you are not familiar with recursive CTEs.) Finally, I calculate the total taxable amount adjusted for previous remaining loss if necessary.
WITH RECURSIVE
source AS (
SELECT row_number() OVER (ORDER BY ym) AS rid, *
FROM RESULTS
),
losses AS (
SELECT s.*, 0 AS res_loss
FROM source AS s
WHERE rid = 1
UNION ALL
SELECT s.*, iif(l.res_loss + l.profitloss < 0, l.res_loss + l.profitloss, 0) AS res_loss
FROM source AS s, losses AS l
WHERE s.rid = l.rid + 1
)
SELECT ym, profitloss, iif(profitloss + res_loss > 0, profitloss + res_loss, 0) AS tax
FROM losses
ORDER BY ym;

DAX Measure with different granularities

I'm looking for help with how to write a specific DAX measure. Here is a simplified version of my data and model:
Tables:
Model:
Measures:
Total Amt:=SUM(Amounts[Amt])
Total Pos Amt:=SUMX(Amounts, IF([Amt]<0,0,[Amt]))
Total Amt All:=CALCULATE([Total Pos Amt],ALL(Ptr))
Total Amt All 2:=SUMX(Bridge,CALCULATE([Total Pos Amt],ALL(Ptr)))
Total Amt All 3:=SUMX(VALUES(Bridge[Pri]),CALCULATE([Total Pos Amt],ALL(Ptr)))
As you can see in the first PivotTable (where [Pri] & [Ptr] are row fields), the highlighted cells show values with an issue. The [Total Pos Amt] measure sums up the [Amt] column in the Amounts table by iterating through it and evaluating an expression where negative amounts are treated as zero and positive amounts are kept. At a [Pri] level granularity, I want that same logic to apply (i.e. evaluate the expression at a [Ptr] level). The problem with the [Total Amt All] measure is that on the PivotTable I get a row for [Ptr] Z under [Pri] A which I don't want. Measures [Total Amt All 2] and [Total Amt All 3] solve that issue but the subtotals at a [Pri] level are wrong in [Total Amt All 2] and the grand total is wrong in [Total Amt All 3].
Any help would be greatly appreciated! How can I write a measure that won't show a [Ptr] that is not associated with a [Pri] per the Bridge table, but that also correctly sums up the [Total Pos Amt] measure at a [Pri] level?
So one of your problems might be which fields you're using in your PivotTable. I got it work by using your bridge table as the fields:
TotalAmtBridged:=CALCULATE ( SUMX(Amounts, IF([Amt]<0,0,[Amt]) ) , Bridge )
FinalTotalAmt:= Calculate([TotalAmtBridged], ALL(Bridge[Ptr])
And then the PivotTable uses Bridge[Pri] and Bridge[Ptr]. So TotalAmtBridged just forces your total amount to use the Bridge context, and then FinalTotal says ignore Ptr (i.e. for each row we're displaying figure out the total amount for Bridge[Pri] only).
And then the grand total's already doing that, so Bob's your uncle.

Creating multiple sum fields based upon criteria in another field in MS access 2007

I have a table like this,
ID-------Amount-----------Transaction Code----------Branch Code--------Value Date
1--------1523--------------------35-----------------------------99------------------2014/01/01
2--------14---------------------91-----------------------------10------------------2014/01/01
3--------789--------------------35-----------------------------14------------------2014/01/02
4--------5000-------------------85-----------------------------99------------------2014/01/02
5--------6778-------------------35-----------------------------5------------------2014/01/03
6--------8000-------------------20-----------------------------5------------------2014/01/03
7--------5646-------------------20------------------------------99------------------2014/01/03
etc. It will have millions of rows. What I have been trying to do is create a report for each Branch Code.
In that I want to have a sum of the 'amount' grouped by value date for a number of different transaction codes. For example: Report for Branch code '99'would look like
Value Date--------Sum of Transaction Code '35'--------------Sum of Transaction Code '20' AND '85'
2014/01/01 -------------- ??? -------------------------------------------------???
2014/01/02 -------------- ??? ------------------------------------------------???
2014/01/03 ------------ ??? ------------------------------------------------????
etc. This would only sum the amounts where the branch code was 99
And then I want to create a number of different reports with the same structure but for a different branch code. Is this possible?! I am really struggling here. Would be eternally grateful for some suggestions.
One method is to use conditional aggregation. In MS Access, that would look like:
select valuedate,
sum(iif(transactioncode = '35', amount, 0)) as trans_35,
sum(iif(transactioncode = '20' or transactioncode = '85', amount, 0)) as trans_20_85
from tablelikethis
where branchcode = '99'
group by valuedate;

Can't filter out 1.#INF values

SELECT NON EMPTY {{[Measures].[Net Promoter Score],[Measures].[AvgRevenuePerUnit]}} ON COLUMNS ,
NON EMPTY {{Hierarchize(DrilldownLevel(DrilldownLevel(DrilldownLevel([Employees].[Boss].[ALL]))))}}
ON ROWS
FROM (SELECT ({[Employees].[Boss].&[14404]}) ON COLUMNS
FROM [Enterprise]
WHERE FILTER([Employees].[EID].[EID],[Measures].[Avg Revenue Per Unit] > 700))
WHERE ({[Employees].[Active Status].&[False]},{[Roles].[Roster Role].&[486]},{[Roles].[Enterprise Role].&[2]},
{[Locations].[Location].&[6]},{[Areas].[Area].&[3]},{[Markets].[Market].&[1]},{[Regions].[Region].&[2]},
{[Dates].[Date].&[20130218]:[Dates].[Date].&[20130319]})
When I run above query, AvgRevenuePerUnit column shows 1.#INF. To replace 1.#INF with 0, I used query given below but the result is same. I am using WITH MEMBER in a query given below.
WITH MEMBER [Measures].[AvgRevenuePerUnit] AS (IIF([Measures].[Avg Revenue Per Unit] = '1.#INF', 0, [Measures].[Avg Revenue Per Unit])), Format_String = '0.#0'
SELECT NON EMPTY {{[Measures].[Net Promoter Score],[Measures].[AvgRevenuePerUnit]}} ON COLUMNS ,
NON EMPTY {{Hierarchize(DrilldownLevel(DrilldownLevel(DrilldownLevel([Employees].[Boss].[ALL]))))}}
ON ROWS
FROM (SELECT ({[Employees].[Boss].&[14404]}) ON COLUMNS
FROM [Enterprise] WHERE FILTER([Employees].[EID].[EID],[Measures].[Avg Revenue Per Unit] > 700))
WHERE ({[Employees].[Active Status].&[False]},{[Roles].[Roster Role].&[486]},{[Roles].[Enterprise Role].&[2]},
{[Locations].[Location].&[6]},{[Areas].[Area].&[3]},{[Markets].[Market].&[1]},{[Regions].[Region].&[2]},
{[Dates].[Date].&[20130218]:[Dates].[Date].&[20130319]})
I have a cube provided by user and from that cube I query data. It seems to me that actual value in cube is not 1.#INF that's why it doesn't replace with 0. But what is that value if it is not 1.#INF.
Any solution ?
1.#INF or -1.#INF is how Analysis Services displays plus/minus infinity, which technically/mathematically is the result of dividing something by zero.
The best approach to avoid this is in the definition of the measure, which is probably in the calculation script of the cube. You probably have there something like
CREATE MEMBER CurrentCube.[Measure].[AvgRevenuePerUnit] AS A / B
, VISIBLE = 1;
Replace this with
CREATE MEMBER CurrentCube.[Measure].[AvgRevenuePerUnit] AS IIf(B <> 0, A / B, null)
, VISIBLE = 1;
and you are done. Of course, replace A and B as appropriate.
Note: There was a recent update for Analysis Services 2012 which contains a new MDX function Divide which allows to write
CREATE MEMBER CurrentCube.[Measure].[AvgRevenuePerUnit] AS Divide(A, B)
, VISIBLE = 1;
If you and all other users really have to stick with the definition as it is in the cube, and have to rely on WITH clauses in queries, then I think your code could be written like
WITH MEMBER [Measures].[AvgRevenuePerUnit] AS
IIF([Measures].[Avg Revenue Per Unit] = 1 / 0 -- '1.#INF', plus infinity
OR [Measures].[Avg Revenue Per Unit] = -1 / 0, -- '-1.#INF', minus infinity
0,
[Measures].[Avg Revenue Per Unit]),
Format_String = '0.#0'
...
Your approach of using '1.#INF' does not work, as this is a string, and the infinite numbers are numbers and not strings for Analysis Services.

MySQL - Max() return wrong result

I tried this query on MySQL server (5.1.41)...
SELECT max(volume), dateofclose, symbol, volume, close, market FROM daily group by market
I got this result:
max(volume) dateofclose symbol volume close market
287031500 2010-07-20 AA.P 500 66.41 AMEX
242233000 2010-07-20 AACC 16200 3.98 NASDAQ
1073538000 2010-07-20 A 4361000 27.52 NYSE
2147483647 2010-07-20 AAAE.OB 400 0.01 OTCBB
437462400 2010-07-20 AAB.TO 31400 0.37 TSX
61106320 2010-07-20 AA.V 0 0.24 TSXV
As you can see, the maximum volume is VERY different from the 'real' value of the volume column?!?
The volume column is define as int(11) and I got 2 million rows in this table but it's very far from the max of MyISAM storage so I cannot believed this is the problem!? What is also strange is data get show from the same date (dateofclose). If I force a specific date with a WHERE clause, the same symbol came out with different max(volume) result. This is pretty weird...
Need some help here!
UPDATE :
Here's my edited "working" request:
SELECT a.* FROM daily a
INNER JOIN (
SELECT market, MAX(volume) AS max_volume
FROM daily
WHERE dateofclose = '20101108'
GROUP BY market
) b ON
a.market = b.market AND
a.volume = b.max_volume
So this give me, by market, the highest volume's stock (for nov 8, 2010).
As you can see, the maximum volume is VERY different from the 'real' value of the volume column?!?
This is because MySQL rather bizarrely doesn't GROUP things in a sensical way.
Selecting MAX(column) will get you the maximum value for that column, but selecting other columns (or column itself) will not necessarily select the entire row that the found MAX() value is in. You essentially get an arbitrary (and usually useless) row back.
Here's a thread with some workarounds using subqueries:
How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?
This is a subset of the "greatest n per group" problem. (There is a tag with that name but I am a new user so I can't retag).
This is usually best handled with an analytic function, but can also be written with a join to a sub-query using the same table. In the sub-query you identify the max value, then join to the original table on the keys to find the row that matches the max.
Assuming that {dateofclose, symbol, market} is the grain at which you want the maximum volume, try:
select
a.*, b.max_volume
from daily a
join
(
select
dateofclose, symbol, market, max(volume) as max_volume
from daily
group by
dateofclose, symbol, market
) b
on
a.dateofclose = b.dateofclose
and a.symbol = b.symbol
and a.market = b.market
Also see this post for reference.
Did you try adjusting your query to include Symbol in the grouping?
SELECT max(volume), dateofclose, symbol,
volume, close, market FROM daily group by market, symbol