Everyone, I'm building a report using Visual Studio 2012
I want to be able to average a group of values between a specific set of rows.
What I have so far is something like this.
=(Count(Fields!SomeField.Value))*.1
and
=(Count(Fields!SomeField.Value))*.9
I want to use those two values to get the Average of Fields!SomeField.Value between those to numbers of the row. Basically I'm removing the top and bottom 10% of the data and get the middle 80% to average out. Maybe there is a better way to do this? Thanks for any help.
Handle it in SQL itself.
Method 1:
Use NTILE function. Go through this link to learn more about NTILE.
Try something like this
WITH someCTE AS (
SELECT SomeField, NTILE(10) OVER (ORDER BY SomeField) as percentile
FROM someTable)
SELECT AVG(SomeField) as myAverage
FROM someCTE WHERE percentile BETWEEN 2 and 9
if your dataset is bigger
WITH someCTE AS (
SELECT SomeField, NTILE(100) OVER (ORDER BY SomeField) as percentile
FROM someTable)
SELECT AVG(SomeField) as myAverage
FROM someCTE WHERE percentile BETWEEN 20 and 90
METHOD 2:
SELECT Avg(SomeField) myAvg
From someTable
Where SomeField NOT IN
(
SELECT Top 10 percent someField From someTable order by someField ASC
UNION ALL
SELECT Top 10 percent someField From someTable order by someField DESC
)
Note:
Test for boundary conditions to make sure you are getiing what you need. If needed tweak above sql code.
For NTILE: Make sure you NTILE parameter is less(or equal) than the number of rows in the table.
Related
Currently I´m doing this (get pagination and count), in Informix:
select a.*, b.total from (select skip 0 first 10 * from TABLE) a,(select count(*) total from TABLE) b
The problem is that I´m repeating the same pattern - I get the first ten results from all and then I count all the results.
I want to make something like this:
select *, count(*) from TABLE:
so I can make my query much faster. It is possible?
I have a PowerPivot Data Model in Excel 2013. There are several measures that I have grouped into a named set using MDX - something like this:
{[Measures].[Sum of Value1],
[Measures].[Sum of Value2],
[Measures].[Sum of Value3]}
By using this named Set, I can place multiple measures on the rows or columns of an Excel PivotTable in a single action. My question is, is there any way using MDX (or DAX in the PowerPivot screen when working with the individual measures) to filter out or hide the entire set based on a single measure value (whether that measure is included in the set or not)? Preferably, I'm looking for a way to do this without including another member in the set (I.e. Not a measure).
Ror example, if the Sum of Value3 in the above example was zero, I'd want the entire set to be hidden from the pivot table.
I know I could edit the DAX in the Data Model to return BLANK() for each measure included in the set based on the value of another measure, but there may be times I want to show those measures in all cases. This would require writing at least 2 measures for every one I have now which I don't like the thought of doing.
UPDATE:
Sourav's answer looks great, but unfortunately won't work in my particular scenario, I believe, because I'm using the "Create Set using MDX" function (under the Manage Sets option in the Fields, Items, & Sets ribbon menu) within Excel. It will only let me write the MDX as:
IIF([Measures].[Sum of Value3]=0,
{},
{[Measures].[Sum of Value1],[Measures].[Sum of Value2],[Measures].[Sum of Value3]})
And once I add that new set to the PivotTable, it will still display all 3 measures for any members where [Sum of Value3] is 0.
I think I'm going to have to find an approach using DAX and the Excel Data Model measures.
UPDATE 2:
Below is a screenshot to help illustrate. Keep in mind the data source in my example is not an external cube, it's simply an Excel file linked in the Data Model against which MDX queries (with limitations?) can be run. In this example, I would like the set to return only Rows A and C because Sum of Value3 is not zero. However, as you can see, all rows are being returned. Thanks!
You can't choose to hide/unhide members/sets on the fly. Instead, you can use IIF to conditionally return an empty set
WITH SET MyNamedSet AS
IIF([Measures].[Sum of Value3] = 0,
{},
{[Measures].[Sum of Value1],[Measures].[Sum of Value2], [Measures].[Sum of Value3]}
Working example in AdventureWorks for #whytheq(DISCLAIMER - Cube was created by me for testing purposes)
with set abc as
iif([Measures].[Fact Internet Sales Count]>34229,
{
[Measures].[Fact Internet Sales Count],
[Measures].[Extended Amount - Fact Internet Sales]
},
{}
)
SELECT
abc
on 0
from [AdventureWorksDW]
where [Due Date].[Year].&[2004]
As you can see, the scope IS changing the results.
An alternative would be to create a dummy measure that returns null or 1 depending on your [Measures].[Sum of Value3]. Then multiply all other target measures by this dummy measure.
Here is an example of you scenario in AdvWrks:
SELECT
[Product].[Product Categories].[Category].[Components] ON 0
,{
[Measures].[Internet Sales Amount]
,[Measures].[Sales Amount]
,[Measures].[Standard Product Cost]
,[Measures].[Total Product Cost]
} ON 1
FROM [Adventure Works];
Returns this:
Adding the dummy measure and amending the other measures:
WITH
MEMBER [Measures].[isItZero] AS
IIF
(
[Measures].[Internet Sales Amount] = 0
,null
,1
)
MEMBER [Measures].[Sales Amount NEW] AS
[Measures].[Sales Amount] * [Measures].[isItZero]
MEMBER [Measures].[Standard Product Cost NEW] AS
[Measures].[Standard Product Cost] * [Measures].[isItZero]
MEMBER [Measures].[Total Product Cost NEW] AS
[Measures].[Total Product Cost] * [Measures].[isItZero]
SELECT
NON EMPTY //<<<<this is required
{
[Measures].[Internet Sales Amount]
,[Measures].[Sales Amount NEW]
,[Measures].[Standard Product Cost NEW]
,[Measures].[Total Product Cost NEW]
} ON 0
,{} ON 1
FROM [Adventure Works]
WHERE
[Product].[Product Categories].[Category].[Components];
Now this returns:
EDIT
According to your latest edit please just try this (I'm assuming you're using Excel 2013):
Create two new measures to replace two of the existing ones:
Name: "Sum of Value1 NEW"
Definition:
IIF
(
[Measures].[Sum of Value3] = 0
,null
,[Measures].[Sum of Value1]
)
Name: "Sum of Value2 NEW"
Definition:
IIF
(
[Measures].[Sum of Value3] = 0
,null
,[Measures].[Sum of Value2]
)
Now use only these three measures in your pivot and just use the ID dimension in a normal way on rows i.e. do not use the custom set you have already tried.
[Measures].[Sum of Value1 NEW]
[Measures].[Sum of Value2 NEW]
[Measures].[Sum of Value3]
Has ID B should now disappear?
I was trying to get a worst performing product group for a selected date, using bottom count. My aim is to return the amount and not the dimension name. But the query is returning the bottom count based on the default date in the cube and not form the select query. Is there a way to pass the current date into the bottomcount? Below is the sample query which i was using:
with
member worst as
([Measures].[Amount])
set worstgrp as
BOTTOMCOUNT([Product].[Product].Members ,1 , [Measures].[worst])
member worstamount as
sum([worstgrp],[Measures].[Amount])
select
{[worstamount]} on 0,
([date].[date].[month-day].[18 Jul 2014]) on 1
from
[Full Details]
We can have multi select on date. And to be exact I am trying to create a calculated member in the cube and use that cube for an ad hoc report usinfg excel. So I guess we cannot pu the date in where clause, but only in select clause.
Just define your set as follows:
set worstgrp as BOTTOMCOUNT([Product].[Product].Members ,1 ,
sum(EXISTING [date].[date].Members, [Measures].[worst]))
In MySQL while there is an AVG function, there is no Median. So I need to create a way to compute Median value for sales figures.
I understand that Median is the middle value. However, it isn't clear to me how you handle a list that isn't an odd numbered list. How do you determine which value to select as the Median, or is further computation needed to determine this? Thanks!
I'm a fan of including an explicit ORDER BY statement:
SELECT t1.val as median_val
FROM (
SELECT #rownum:=#rownum+1 as row_number, d.val
FROM data d, (SELECT #rownum:=0) r
WHERE 1
-- put some where clause here
ORDER BY d.val
) as t1,
(
SELECT count(*) as total_rows
FROM data d
WHERE 1
-- put same where clause here
) as t2
WHERE 1
AND t1.row_number=floor(total_rows/2)+1;
I have an Excel spreadsheet which has a pivot table on it. The data itself is quite simple, Number of Units and a Discount (percentage from 0 to 100), pivoted on date across the top and customer down the left hand side. Those numbers are straight from a SQL view, so the pivot table source is just:
SELECT * FROM UnitDiscountView
All was looking fine until I attempted to add a calculated field of TotalCost (Each unit will costs £200) to the pivot table:
= (200 *NrUnits ) * ((100-Discount)/100)
The total at the bottom was negative, and vastly more than I was expecting as a number. If I select all the cells, then the sum which appear in the status bar at the bottom is what I would expect, but the Total field at the bottom is over a hundred times bigger, and negative to boot.
I am stumped. I have searched since Friday without finding anything which will help me to solve this. Any pointers on where to start looking for the solution would be greatly appreciated. I should mention that SQL is my forte, not Excel. I haven't used Excel's Pivot tables before last week, so I am probably missing something really obvious.
Calculated fields will work with the totals:
200 * (Sum of NrUnits) * ((100 - [Sum of Discount]) / 100 )
So for your total row, if Sum of Discount is greater than 100 (adding up all the Sums of Discount on the pivot table), the part of your formula (100-Sum of Discount) will be returning a negative number, hence the negative value.
What I normally do is to add another column to the table to the right of the values returned from the query. I will add my formulas there, then do the pivot table on the resized table.
If you have formatted the returned SQL query as a table (or list in Excel 2003), the pivot table source range should even resize by itself.
I found the answer.
Excel was effectively doing this for the total:
= (200 * sum(NrUnits)) * ((100-sum(Discount))/100)
Which isn't even close to what I wanted:
= sum((200-NrUnits) * ((100-Discount) * 100)))
I got round it by changing the SQL from the view to be:
SELECT *, NrUnits*((100-Discount)*100) AS EffectiveUnits
FROM UnitDiscountView
And the Calculated field to:
= EffectiveUnits * 200