Changing field fill of max value in column groups on SSRS 2014 - reporting-services

I have a table in SSRS that has both row and column groups.
For each row group [Cat], I need to highlight the highest value in the column group, which is the sum of all counts for that category in a given month.
Can't for the life of me figure it out, so if anyone could help that would be great!
Thanks
Example of dataset
This is what I'm aiming for
Table in Design View
Current outcome

The problem you will face is that you will have to try to use nested aggregates with scopes defined. This might be possible (but I don't think it is...)
There is a fairly simple way to fix it though. I can;t give an exact answer as I don;t know what your dataset looks like but typically you would have to make some changes to your dataset, then its simple.
So assuming your dataset looks something like this
Cat myDate counts
A 20171001 90
A 20171001 6
B 20171001 18
C 20171001 1
A 20171101 100
A 20171101 20
....
....
Then aggregate everything so the report does not have to do any real aggregation with something like
SELECT
*
, max(counts) OVER(PARTITION BY Cat) as maxInCat
FROM (
SELECT
Cat, myDate
, SUM(counts) as counts
FROM myTable
GROUP BY Cat, myDate
) x
This will give you a dataset with an additional column maxInCat. This column will contain the maximum value in each category so we can compare against this in the report.
The expression can then be something like
=IIF(SUM(Fields!counts.Value)>0 and SUM(Fields!counts.Value) = Fields!maxInCat.Value, "Yellow", Nothing)
EDIT
I've updated the actual backcolor expression as it didn't account for blanks/zeros
Ignoring the fact the the columns are not sorted as I don't have time, here's the result

Here's an answer that I think does what you need:
declare #Table as table
(
[Cat] char(1),
[Sector] tinyint,
[Counts] int,
[Date] date
);
insert into #Table
(
[Cat],
[Sector],
[Counts],
[Date]
)
values
('A', 1, 4103, '2017-10-01'),
('A', 1, 3001, '2017-11-01'),
('A', 1, 1128, '2017-12-01'),
('A', 1, 5917, '2018-01-01'),
('A', 1, 9594, '2018-02-01'),
...
So you know where the data is coming from.
with [AggregatedData] as
(
select
t.Cat,
t.Sector,
t.Counts,
t.[Date],
sum(t.Counts) over (partition by t.Cat, t.[Date]) as [SumCounts]
from #Table as [t]
)
select
ad.Cat,
ad.Sector,
ad.Counts,
ad.[Date],
ad.SumCounts,
max(ad.SumCounts) over (partition by ad.[Date]) as [MaxSumCounts]
from [AggregatedData] as [ad]
Then in SSRS, you can use:
=iif(IsNothing(Fields!SumCounts.Value) = FALSE AndAlso Fields!SumCounts.Value = Fields!MaxSumCounts.Value, "Yellow", "Transparent")
Which gives:

Related

SQL stament groups rows and calculate average

I am stuck with the following issue. I have 1 table that looks like this:
field_number.. Value
````````````````````````````````
1 ......................... 1
2 ..........................1
3 ......................... 2
4 ..........................2
etc.
I want to group different fieldnumbers and have an average for the value column. So the output should be:
field_number................Value
name(1,2)...................... 1.............. ((1+1)/2)
name(3,4)...................... 2.............. ((2+2)/2)
I have checked previous questions but cannot find any question that covers this issue (I might search on the wrong keywords though). So if this has already been covered my appologies, but any help or a point to a previous answer would be appreciated.
** =============UPDATE============= **
I went through your suggestions but did not get it right. So I am trying to be more specific. I almost have the result I want apart from the fact I want to have a fixed value in one of my columns. I have the following query:
Select
Avg(wp_rg_lead_detail.value),
wp_rg_lead_detail.field_number,
From
wp_rg_lead_detail
Where
wp_rg_lead_detail.field_number In (15, 17, 24) A
UNION
Select
Avg(wp_rg_lead_detail.value),
wp_rg_lead_detail.field_number,
From
wp_rg_lead_detail
Where
wp_rg_lead_detail.field_number In (16, 108, 18)
etc.
This gives me a table with two columns
wp_rg_lead_detail.value................field_number
4.3 (average)..............................15 (first value of av calculation)
What I want is to change the field number (15 in this case) in a fixed value (text). What and how should I add this to the query?
SELECT avg(value) FROM table WHERE field_number in (1,2)
SELECT avg(value) FROM table WHERE field_number in (3,4)
If your table is really this simple, you can also get away with:
select distinct
Value,
count(Value) as '#'
from table_name
group by Value
If you acctually want to group by a range, than you can put the logic of the range in your grouping clause (see this fiddle)
select distinct
avg(Value) as average,
floor(Value),
count(Value) as '#'
from table_name
group by floor(Value)
In the fiddle I used grouping on whole integers, but you can make that as complex as you like (see, for instance, this example)
If you are actually also interested in your corresponding fields, use group_concat() like so
select
Value,
group_concat(
distinct field_number
order by Value
) as fields
from table_name tn1
group by Value
order by Value
output:
Value | fields
---------------------------------
1 | 1,2
2 | 3,4
See this fiddle implemented from this blog post
For a generalized answer.
SELECT CONCAT('name','(',GROUP_CONCAT(field_number),')') AS field_number,
AVG(Value) as Value
FROM table_name
group by table_name.`Value`
Hope this helps.

mysql count distinct value

I have trouble wondering how do I count distinct value. using if on the select column
I have SQLFIDDLE here
http://sqlfiddle.com/#!2/6bfb9/3
Records shows:
create table team_record (
id tinyint,
project_id int,
position varchar(45)
);
insert into team_record values
(1,1, 'Junior1'),
(2,1, 'Junior1'),
(3,1, 'Junior2'),
(4,1, 'Junior3'),
(5,1, 'Senior1'),
(6,1, 'Senior1'),
(8,1, 'Senior2'),
(9,1, 'Senior2'),
(10,1,'Senior3'),
(11,1, 'Senior3'),
(12,1, 'Senior3')
I need to count all distinct value, between Junior and Senior column.
all same value would count as 1.
I need to see result something like this.
PROJECT_ID SENIOR_TOTAL JUNIOR_TOTAL
1 3 3
mysql query is this. but this is not a query to get the result above.
SELECT
`team_record`.`project_id`,
`position`,
SUM(IF(position LIKE 'Senior%',
1,
0)) AS `Senior_Total`,
SUM(IF(position LIKE 'Junior%',
1,
0)) AS `Junior_Total`
FROM
(`team_record`)
WHERE
project_id = '1'
GROUP BY `team_record`.`project_id`
maybe you could help me fix my query above to get the result I need.
thanks
I think you want this:
SELECT
project_id,
COUNT(DISTINCT CASE when position LIKE 'Senior%' THEN position END) Senior_Total,
COUNT(DISTINCT CASE when position LIKE 'Junior%' THEN position END) Junior_Total
FROM team_record
WHERE project_id = 1
GROUP BY project_id
The CASE will return a null if the WHEN is false (ie ELSE NULL is the default, which I omitted for brevity), and nulls aren't counted in DISTINCT.
Also, unnecessary back ticks, brackets and qualification removed.

WHERE clause in SSRS expression for max function

I have for example a query with return something as it
route value
1 3
2 2
3 4
4 5
5 1
then I need to put in 2 textbox the max and the min route so in sql this would be
select top 1 route from table where value=(select max(value) from table)
I add a image done in excel, how this would be.
I believe this is so easy but I dont have idea how to get it.
I got using expression, this was extactly expression
="Route "+
Convert.ToString (
Lookup(max(fields!value.Value),fields!value.Value ,fields!route.Value,"mydataset")
)
changing max for min, for the other...
thanks everyone.
I believe the query you're looking for would be:
With Min_Max_CTE as (
Select MIN(value) as Min_Value
, MAX(value) as Max_Value
From Table
)
Select Top 1 'Min' as Type
, T.route
, T.value
From Table T
Inner Join Min_Max_CTE CTE
on T.value = CTE.Min_Value
Union All
Select Top 1 'Max' as Type
, T.route
, T.value
From Table T
Inner Join Min_Max_CTE CTE
on T.value = CTE.Max_Value
Order by Type desc --This will put the Min Route first followed by the Max Route
Then, put that query into a dataset, and then create a tablix and use the Type, route, and value fields to return the minimum route and the maximum route. It should end up being set up just like your excel section with the min and max routes above.
You can do this SSRS by using a couple of separate tables. Your example data:
And two tables in the Designer:
Since the tables only have header rows, only the first row in the table will be displayed.
To make sure we get the MAX and MIN values in the two tables, each table needs to order its Dataset appropriately, i.e. by Value by descending and ascending respectively.
MAX table:
MIN table:
Which gives your expected result:

Break Numbers List Into Min and Max Ranges

Brain is not working today and my google skills are failing me.
I have a column of numbers ranging from 1 - 1000. I want to dump the min and max values for 100 (or whatever I chose) record ranges into a temp table. The plan is to use this temp table to process ranges of records (in this example 100 at a time) in a larger table.
Swear I have done this before with a CTE but then I had something to group on. Here I just want to break up a single list of numbers into ranges of X.
The output from the temp table should look like:
Min Max
0 99
100 199
200 299
300 399
etc.
Thanks!
You can use this trick from Stuart Ainsworth:
http://codegumbo.com/index.php/2009/01/25/building-ranges-using-a-dynamically-generated-numbers-table/
Numbers tables are awesome, but he uses a dynamically generated numbers table, which is even awesome...r.
If you know all numbers are present in the source table, you can use a recursive CTE to generate the number ranges:
; with numbers as
(
select 0 as a
, 99 as b
union all
select a+100
, b+100
from numbers
where a < 900
)
select *
from numbers
If the source table is sparsely populated, you can limit it to numbers that are actually present like:
... insert CTE from above here ...
select min(ot.NumberColumn)
, max(ot.NumberColumn)
from numbers
left join
OtherTable ot
on ot.NumberColumn between numbers.a and numbers.b
group by
numbers.a
enter code hereI have been having a play with a CTE after you posted this and came up with the following, I would be interested to hear if it works for you at all.
DECLARE #segment int = 100
;
WITH _CTE
(rowNum, value)
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY col01) -1, col01
FROM dbo.testTable
)
SELECT rowNum/#segment AS Bucket, MIN(Value) AS MinVal, MAX(Value) AS MaxVal
FROM _CTE
group by rowNum/#segment
ORDER BY Bucket
;
col01 in this case is the column that you want the min/max range values from, as is TestTable.

Select multiple sums with MySQL query and display them in separate columns

Let's say I have a hypothetical table like so that records when some player in some game scores a point:
name points
------------
bob 10
mike 03
mike 04
bob 06
How would I get the sum of each player's scores and display them side by side in one query?
Total Points Table
bob mike
16 07
My (pseudo)-query is:
SELECT sum(points) as "Bob" WHERE name="bob",
sum(points) as "Mike" WHERE name="mike"
FROM score_table
You can pivot your data 'manually':
SELECT SUM(CASE WHEN name='bob' THEN points END) as bob,
SUM(CASE WHEN name='mike' THEN points END) as mike
FROM score_table
but this will not work if the list of your players is dynamic.
In pure sql:
SELECT
sum( (name = 'bob') * points) as Bob,
sum( (name = 'mike') * points) as Mike,
-- etc
FROM score_table;
This neat solution works because of mysql's booleans evaluating as 1 for true and 0 for false, allowing you to multiply truth of a test with a numeric column. I've used it lots of times for "pivots" and I like the brevity.
Are the player names all known up front? If so, you can do:
SELECT SUM(CASE WHEN name = 'bob' THEN points ELSE 0 END) AS bob,
SUM(CASE WHEN name = 'mike' THEN points ELSE 0 END) AS mike,
... so on for each player ...
FROM score_table
If you don't, you still might be able to use the same method, but you'd probably have to build the query dynamically. Basically, you'd SELECT DISTINCT name ..., then use that result set to build each of the CASE statements, then execute the result SQL.
This is called pivoting the table:
SELECT SUM(IF(name = "Bob", points, 0)) AS points_bob,
SUM(IF(name = "Mike", points, 0)) AS points_mike
FROM score_table
SELECT sum(points), name
FROM `table`
GROUP BY name
Or for the pivot
SELECT sum(if(name = 'mike',points,0)),
sum(if(name = 'bob',points,0))
FROM `table
you can use pivot function also for the same thing .. even by performance vise it is better option to use pivot for pivoting... (i am talking about oracle database)..
you can use following query for this as well..
-- (if you have only these two column in you table then it will be good to see output else for other additional column you will get null values)
select * from game_scores
pivot (sum(points) for name in ('BOB' BOB, 'mike' MIKE));
in this query you will get data very fast and you have to add or remove player name only one place
:)
if you have more then these two column in your table then you can use following query
WITH pivot_data AS (
SELECT points,name
FROM game_scores
)
SELECT *
FROM pivot_data
pivot (sum(points) for name in ('BOB' BOB, 'mike' MIKE));