In my report, I've the data in the following way
The Rank is on the Revenue grouped by Category - RANK(Revenue by Category Name)
In the Results, the report is grouped by Category Name(By placing the Category Name in the sections)
The Revenue is sorted in descending order, so that when the RSUM is calculated, the first result should give Top Revenue, the third result should give the sum of top three revenues.
RSUM - RSUM(Revenue by Category Name)
when the Revenue is sorted(in the criteria),so that the results are expected as explained above, I'm getting the Rank to be 1 for most of the records and a few records with 2 and 3 rank and so the RSUM is also resulting in the same way.
If I don't sort with respect to Revenue , then the Rank and RSUM are behaving as expected but the records are being sorted by ID by default and this does not meet the purpose of RSUM top get the sum of Top 'n' Revenue.
You probably need to order by category first (either ascending or descending – probably doesn't really matter), then by Revenue (descending). Otherwise each of your categories are distributed throughout your dataset.
Related
My goal is to create measure to get top 3 customer Names and there respective sales.
I am using the below measure to bring top 3 names along with there sales. The below measure is returning all the rows. I fail to understand why this is happening and why filtering is not happening for top 3 customers
topN = calculate(sum(Sale[Total Excluding Tax]),
TOPN(3,
values(Sale[Employee Name]),
calculate(sum(Sale[Total Excluding Tax]))
)
)
Sale[Employee Name] is calculated column and is coming from another table Employee by using Employee Name = RELATED(Employee[Employee])
The DAX is working properly and grabbing top 3 records. Order/sorting is important. You need to order your results.
Create a calculate column [Total Excluding Tax] to sum up the Total excluding tax. Then use that column in a measure; try something like:
Top Sales = TOPN ( 3, ALLSELECTED( 'Sale' ), [Total Excluding Tax]), desc)
I'm developing an application that uses a tabular database to show some business data.
I need to provide some basic filtering over measures values (equal to, greater than, lesser than etc.) and I'm currently analyzing the proper way to generate the MDX.
Looking at some documentation (and other threads on this site), I found that the most efficient approach would be using the FILTER or HAVING functions to filter out undesired values.
Unfortunately all examples normally include measures on one axis and dimension member on the other, but I potentially have dimension members in both axis and can't find a proper solution to use such functions to filter by measure value.
What have I done so far?
To make it easier to explain, let's say that we want to get the yearly sales quantities by product class filtering quantity > 1.3 milions
Trying to use HAVING or FILTER Functions, the resulting MDX I came up with is
SELECT
NON EMPTY {[YearList].[Year].[Year].MEMBERS * [Measures].[Qty]}
HAVING [Measures].[Qty] > 1.3e6 ON COLUMNS,
NON EMPTY {[Classes].[cClass].[cClass].MEMBERS}
HAVING [Measures].[Qty] > 1.3e6 ON ROWS
FROM [Model]
or
SELECT
NON EMPTY FILTER({[YearList].[Year].[Year].MEMBERS * [Measures].[Qty]},
[Measures].[Qty] > 1.3e6) ON COLUMNS,
NON EMPTY FILTER({[Classes].[cClass].[cClass].MEMBERS} ,
[Measures].[Qty] > 1.3e6) ON ROWS
FROM [Model]
But this is of course leading to unexpected result for the final user because the filter is happening on the aggregation of the quantities by the dimension on that axis only, which is greater then 1.3M
The only way I found so far to achieve what I need is to define a custom member with an IIF statement
WITH
MEMBER [Measures].[FilteredQty] AS
IIF ( [Measures].[Qty] > 1.3e6, [Measures].[Qty], NULL)
SELECT
NON EMPTY {[YearList].[Year].[Year].MEMBERS * [Measures].[FilteredQty]} ON COLUMNS,
NON EMPTY {[Classes].[cClass].[cClass].MEMBERS} ON ROWS
FROM [Model]
The result is the one expected:
Is this the best approach or I should keep using FILTER and HAVING functions? Is there even a better approach I'm still missing?
Thanks
This is the best approach. You need to consider how MDX resolves result. In the example above it is a coincidence that your valid data in a continous region of first four columns of first row. Lets relax the filtering clause and make it >365000. Now take a look at last row of the result, the first two columns and the last column are eligible cells but the third and fourth column is not eligible. However your query will report it as null and the non empty function will not help. The reason is that non empty needs the entire row to be null
Now the question that why filter is not eliminating the cell? Filter will eliminate a row or column when the criteria is greater then the sum on the other axis. So if filter is on columns the filter value has to be greater than the sum of rows for that column. Take a look at the sample below as soon as you remove the comments the last column will be removed.
select
non empty
filter(
([Measures].[Internet Sales Amount]
,{[Date].[Calendar Year].&[2013],[Date].[Calendar Year].&[2014]}
,[Date].[Calendar Quarter of Year].[Calendar Quarter of Year]
),([Date].[Calendar Year].currentmember,[Date].[Calendar Quarter of Year].currentmember,[Product].[Subcategory].currentmember,[Measures].[Internet Sales Amount])>45694.70--+0.05
)
on columns
,
non empty
[Product].[Subcategory].members
on rows
from
[Adventure Works]
Edit another sample added.
with
member [Measures].[Internet Sales AmountTest]
as
iif(([Date].[Calendar Year].currentmember,[Date].[Calendar Quarter of Year].currentmember,[Product].[Subcategory].currentmember,[Measures].[Internet Sales Amount])>9000,
([Date].[Calendar Year].currentmember,[Date].[Calendar Quarter of Year].currentmember,[Product].[Subcategory].currentmember,[Measures].[Internet Sales Amount]),
null
)
select
non empty
({[Measures].[Internet Sales Amount],[Measures].[Internet Sales AmountTest]}
,{[Date].[Calendar Year].&[2013]}
,[Date].[Calendar Quarter of Year].[Calendar Quarter of Year]
)
on columns
,
non empty
[Product].[Subcategory].[Subcategory]
on rows
from
[Adventure Works]
Im trying to build a query that pulls the information from one table and also pulls the max and min value of that product in another table but cannot seem to get this to work.
This is what I have:
$rentals = Rentals::select('rentals.main_image','rentals.rental_name','rentals.slug','rentals.summary',DB::raw('max(prices.price) as price_high'),DB::raw('min(prices.price) as price_low'))
->leftjoin('prices', 'rentals.id', '=', 'prices.rental_id')
->where('destination',$destination_id)->paginate(6);
This returns 1 row ( there should be 88 ) and it gets me the highest and lowest price in the table regardless of rental_id. There are other factors that will filter into this like dates but for now I just need the rental info plus the highest and lowest price for that rental.
I have a table created. With one column named states and another column called land area. I am using oracle 11g. I have looked at various questions on here and cannot find a solution. Here is what I have tried so far:
SELECT LandAreas, State
FROM ( SELECT LandAreas, State, DENSE_RANK() OVER (ORDER BY State DESC) sal_dense_rank
FROM Map )
WHERE sal_dense_rank >= 5;
This does not provide the top 5 land areas as far as number wise.
I have also tried this one but no go either:
SELECT * FROM Map order by State desc)
where rownum < 5;
Anyone have any suggestions to get me on the right track??
Here is a samle of the table
states land areas
michagan 15000
florida 25000
tennessee 10000
alabama 80000
new york 150000
california 20000
oregon 5000
texas 6000
utah 3000
nebraska 1000
Desired output from query:
States land area
new york 150000
alabama 80000
florida 25000
california 20000
Try:
Select * from
(SELECT State, LandAreas FROM Map ORDER BY LandAreas DESC)
where rownum < 6
Link to Fiddle
Use a HAVING clause and count the number state states larger:
SELECT m.state, m.landArea
FROM Map m
LEFT JOIN Map m2 on m2.landArea > m.landArea
GROUP BY m.state, m.landArea
HAVING count(*) < 5
ORDER BY m.landArea DESC
See SQLFiddle
This joins each state to every state whose area is greater, then uses a HAVING clause to return only those states where the number of larger states was less than 5.
Ties are all returned, leading to more than 5 rows in the case of a tie for 5th.
The left join is needed for the case of the largest state, which has no other larger state to join to.
The ORDER BY is optional.
Try something like this
select m.states,m.landarea
from map m
where (select count(‘x’) from map m2 where m2.landarea > m.landarea)<=5
order by m.landarea
There are two bloomers in your posted code.
You need to use landarea in the DENSE_RANK() call. At the moment you're ordering the states in reverse alphabetical order.
Your filter in the outer query is the wrong way around: you're excluding the top four results.
Here is what you need ...
SELECT LandArea, State
FROM ( SELECT LandArea
, State
, DENSE_RANK() OVER (ORDER BY landarea DESC) as area_dr
FROM Maps )
WHERE area_dr <= 5
order by area_dr;
... and here is the SQL Fiddle to prove it. (I'm going with the statement in the question that you want the top 5 biggest states and ignoring the fact that your desired result set has only four rows. But adjust the outer filter as you will).
There are three different functions for deriving top-N result sets: DENSE_RANK, RANK and ROW_NUMBER.
Using ROW_NUMBER will always guarantee you 5 rows in the result set, but you may get the wrong result if there are several states with the same land area (unlikely in this case, but other data sets will produce such clashes). So: 1,2,3,4,5
The difference between RANK and DENSE_RANK is how they handle ties. DENSE_RANK always produces a series of consecutive numbers, regardless of how many rows there are in each rank. So: 1,2,2,3,3,3,4,5
RANK on the other hand will produce a sparse series if a given rank has more than one hit. So: 1,2,2,4,4,4.
Note that each of the example result sets has a different number of rows. Which one is correct? It depends on the precise question you want to ask.
Using a sorted sub-query with the ROWNUM pseudo-column will work like the ROW_NUMBER function, but I prefer using ROW_NUMBER because it is more powerful and more error-proof.
I am trying to figure out how to sum and group on a sub-query that does a first level sum and group, in Ruby ActiveRecord.
I can get the sums of the sub-query using a named scope and a subsequent select function. That gets executed in a loop that builds a table with a row for each payment, with payment totals on the top of each cashadvance group, and totals for each syndicator group for all the syndicators cashadvances:
#funder
.cashadvance_syndicators(#start_date, #end_date)
.select("sum(amount) as amount, percent_syndicated, management_fee, residual_commission")
.where(['cashadvance_syndicators.iso_id = ?', cs.iso_id])
.group('cashadvance_syndicators.id')
where a funder has many cashadvances, which has many payments to borrowers in which many cashadvance syndicators participate in based on a percent of the whole loan.
I need to be able to sum the amounts in the columns selected for each syndicator.