I'm using SSRS linked to MySQL by ODBC. My query sums the payment amount by customer, and sorts by amount desc. I want to use this to create a LeaderBoard in SSRS, showing the Rank, and only including the top 10 customers.
Option 1:
Do an additional query on my group query in SQL, adding the Row Number.
Option 2:
Add a calculated field in SSRS.
Option 1 seemed bulky, so started with Option 2; I added a calculated field to the dataset called "Rank", defined as =RowNumber("DataSet1")
I added a calculated field to the dataset called "Rank", defined as: =RowNumber("DataSet1")
But I got the following error:
The expression used for the calculated field 'Rank' includes an aggregate, RowNumber, RunningValue, Previous or lookup function. Aggregate, RowNumber, RunningValue, Previous and lookup functions cannot be used in calculated field expressions.
So, I then added it to the actual tablix, and I was able to get the Rank to show correctly.
(When I did this, it automatically added an extra column to my dataset.
I then wanted to filter the top 10 customers.
I first tried by "bottom 10" on this new field, but it didn't work. (Seems this field is all zeros in the actual dataset.)
I then tried by "top 10" on the payment amount, but received an error that the filter only supports Integers.
So I tried to convert the payment amount to Integer in MySQL, using CAST and Convert, but they don't support conversion to Integer, and SSRS didn't like 'SIGNED' or any of the other options.
I then started trying Option 1, which was building the query into MySQL.
I added:
SET #rank=0;
SELECT #rank:=#rank+1 AS Rank, ...
This works in MySQL, but I get an error when I paste that query into the report definition on SSRS.
Any ideas?
Rather than setting #rank=0 in a separate statement, try setting it in a subquery cross-joined to the main query - like so:
SELECT #rank:=#rank+1 AS Rank, ...
FROM (SELECT #rank:= 0) r
CROSS JOIN ...
Related
I have a SSRS expression where I'm calculating and an average setup time, but because of multiple, and different, postings against each order I'm needing to only take the average setup times for unique orders. Because of the need for other parts of the report to include ALL postings I cannot group or filter out the multiple order postings anywhere but this single expression. So I have the following expression:
=AVG(iif(IsNumeric(Fields!Setup.Value), CDbl(Fields!Setup.Value), 0))
And I'm essentially needing the proper syntax for the above expression rewritten to...psuedocode incoming...
=IIf((Fields!Order_Number.Value) is unique), AVG(iif(IsNumeric(Fields!Setup.Value), CDbl(Fields!Setup.Value), 0), else nothing)
I'm pretty sure a CountDistinct clause will resolve this issue, but I'm having difficulty finding the proper syntax.
Add a column to identify a unique row for each order:
ROW_NUMBER() OVER (PARTITION BY YourOrderID ORDER BY YourOrderID) as RowNumber
Add a calculated field to your dataset. Let’s call it “FilteredSetup”:
=IIf(Fields!RowNumber.Value = 1, Fields!Setup.Value, Nothing)
Now you can refer to this new column in your report and it will aggregate correctly:
=Sum(Fields!FilteredSetup.Value)
Hello I am trying to present the data in a matrix format & I am using TOP N in the table level. The tabular data in Desc order & I want to divide the top 10 numbers with their subtotal but it is considering total of entire data set.
Using the formula - =RunningValue(Fields!Total.Value,Sum,"DataSet3")/2439 I am getting the view but if I use a filter it will give wrong result.
Please suggest what we can use instead of 2439 so that after using filter it will be an automated process & using sum of those TOP 10.
The problem with Aggregates within an SSRS table is that they act on the filtered and sorted dataset, not the original SQL dataset, depending on where the SSRS filter and sorting is applied. In general, if you want to do calculations on a subset of your data, it's handy to have a unique value in the SQL dataset on which you can group and run SSRS aggregates.
If you're trying to do a group by X, you could try doing a row_number() over (partition by [x] group by [y] desc) and then use the following formula. In this formula, it would group the data into groups of whatever #X is (e.g., if #X is ten, then you'd have 0 for the first group of ten, 1 for the second group, 2 for the third group, etc).
Floor((Row_Number() over (Order by [rowID]) - 1)/#X) as Row_Grouping
I have an SSRS Report, in the database there is a column by name Total_running_hours.
There are more than one record for a single Cycle_number like more than 1 row with same Cycle_number but different Block_numbers and the value in Total_running_hours field will be same for all the rows with same Cycle_number. Eg. 1 Cycle number with 4 diff block_numbers contain same Total_running_hours for all 4 rows.
Now the problem is, in the group footer if I put this field then it will show the Total_running_hours value only once which is correct, but my final requirement is,
I need to get the sum of this field in the Report footer which need to display the sum group wise. No matter how many rows are there for a single Cycle_number it has to take only once and display the result.
I tried in different ways like
=sum(ReportItems!textbox204.Value) // name of text box in Group footer
Error: Report item expressions can only refer to other report items
within the same grouping scope or a containing grouping scope.
=sum(Fields!total_running_hours.Value,Group_name)
Error: The scope parameter must be set to a string constant that is
equal to either the name of a containing group, the name of a
containing data region, or the name of a data set.
Can any one please help me in getting the sum Group wise
Thank you in advance.
I found solution for this Problem.
We cannot simply sum the Total_Running_hours value as this would give us duplicates and the incorrect answer. We cannot sum the reporting services group as it goes out of scope
There is no SUM DISTINCT available in Reporting Services 2005 so we can't get the distinct value that way.
Since the query may not return a particular Cycle_Number Type we cannot use that as a filter.
The solution found was to add a column of the row number within a windowed set partitioned by the Cycle_Number like this
ROW_NUMBER() OVER (PARTITION BY Cycle_Number ORDER BY Cycle_Number ) AS 'RowNumber'
Then in the reports’ footer total column we put an expression that only takes the first row’s value to sum and converts all other rows to zero in that windowed set.
=SUM(IIF(Fields!RowNumber.Value=1,Fields!Total_Running_hours.Value,0))
After using this if u found any error in textbox like #Error
Then try this
=SUM(IIF(Fields!RowNumber.Value=1,CDbl(Fields!Total_Running_hours.Value),CDbl(0.0)))
I have a column name 'APPs % of total' and it requires two different data sets to be populated .This doesn't seem to work. Any tips will be appreciated. Thanks
=(Fields!AppQty.Value/Fields!AppQty.Value,"second dataset")
The problem is: how does SSRS know which row to pull from the second dataset to get the field? So you have to use aggregation or lookups:
Method 1: Simply aggregate at the current level
There's usually no need for a secondary dataset just for your sums. You can aggregate at the group level within the current dataset by using the following formula:
=Fields!AppQty.Value / SUM(Fields!AppQty.Value, "table1_Group1")
where table1_Group1 is the group where the data is summarised.
Method 2: Aggregate the entire dataset
Aggregate at the dataset level for the either the current dataset or a secondary one:
=Fields!AppQty.Value / SUM(Fields!AppQty.Value, "SomeDataset")
Method 3: Lookup the value from another dataset
You'll need a dataset that sums the values at a group level. You usually achieve this result using method 1 and grouping, but here for completeness. So, let's say you are grouping by DepartmentId, you would have a dataset that aggregates like so:
SELECT DepartmentId, SUM(AppQty) AS AppQty
FROM MyTable
GROUP BY DepartmentId
Then lookup the appropriate value for the department from the current row (in the current table's dataset):
=Fields!AppQty.Value / Lookup(Fields!DepartmentId.Value, Fields!DepartmentId.Value, Fields!AppQty.Value, "SummaryDataset")
So the Lookup matches the DepartmentId from this dataset with the DepartmentId in the SummaryDataset and returns the AppQty value.
This seems like it should be simple but I can't find anything yet. In Reporting Services I have a table with up to 6 rows that all have calculated values and dynamic visibility. I would like to sum these rows. Basically I have a number of invoice items and want to make a total. I can't change anything on the DB side since my stored procedures are used elsewhere in the system. Each row pulls data from a different dataset as well, so I can't do a sum of the dataset. Can I sum all the rows with a table footer? Similarly to totaling a number of rows in Excel? It seems very redundant to put my visibility expression from each row into my footer row to calculate the sum.
A few ways you could achieve this:
1. Do the calculation in the SQL and sum that field, like so:
SELECT Quantity, Amount, Quantity * Amount As TotalAmount FROM MyTable
Then just use the TotalAmount field in your Detail row and sum it in the footer.
2. Create a second Dataset that calculates the total for you and use that in your footer instead of a sum:
=Sum(Fields!TotalAmount.Value, "MyTotalingDataset")
3. Do it using custom code. Right-click on the Layout space choose Properties and click on the Code tab. Put in the following code:
Public Dim TotalAmount As Double = 0
Public Function CalculateRowTotal(ThisValue As Double, ThatValue As Double) As Double
TotalAmount = TotalAmount + (ThisValue * ThatValue)
Return ThisValue * ThatValue
End Function
On the Detail band, make the column where you sum the field have this expression:
=Code.CalculateRowTotal(Fields!Quantity.Value, Fields!Amount.Value)
This will execute the code above and do your calculation plus calculate the total sum in the process.
The Footer band displays the total sum so the column has the expression:
=Code.TotalAmount
And you're done. Just be careful because you aren't guaranteed the order in which your code will execute and for some reports it will execute the footer first (for example, if you use the Sum of the rows in the Detail band) which would make the total zero as the Detail band calculations haven't happened yet, but for the general case this should work.
You could change the db as follows.
Did you know you can get aggregated results in SQL without aggregating the data?
Just add an extra column to the dataset as follows:
,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Total'
In the above sample:
OrderQty is the value you wish to sum
SalerOrderID is the equivalent of 'GROUP BY'
You can use the same technique with COUNT, AVG and so on
More information here
http://msdn.microsoft.com/en-us/library/ms189461(SQL.90).aspx
In case you have a problem with the execution order, add a text box below of the table and display TotalAmount in this box.