How to do colour formatting in drilldown pivot report - reporting-services

I have made a Drill down report in SSRS 2008 with one parent group and 4 child group each group field aggregates value under a pivot column.I have to do conditional formatting to change the background color of the pivot field if the particular aggregate value exceeds the input value on each drilldown field.
I have tried multiple expression With 'IIF' and 'SWITCH' condition to change the background color in pivot field in each drill down field.
=switch(
Fields!CIRCLE.Value,"DataSet1" AND (fields!TOTAL.Value>30000,"DataSet1"),"Red",
(Fields!ZONE.Value,"DataSet1" AND (fields!TOTAL.Value>100,"DataSet1"),"Red",
(Fields!CLUSTER.Value,"DataSet1" AND (fields!TOTAL.Value>5000,"DataSet1"),"Red",
(Fields!NODE.Value,"DataSet1" AND (fields!TOTAL.Value>3000,"DataSet1"),"Red","White"
))))
I want the Pivot field Hour with sum as aggregates to turn red on circle level zone level,cluster level and node level like example if the Sum field under pivot column is 700 in 3rd hour and it exceeds 300 then the value at 3rd hour should turn red on circle level.

Try this method:
=switch( Fields!CIRCLE.Value > 30000 AND Fields!TOTAL.Value >30000,"Red",
Fields!ZONE.Value> 100 AND Fields!TOTAL.Value > 100,"Red",
Fields!CLUSTER.Value > 5000 AND Fields!TOTAL.Value > 5000,"Red",
Fields!NODE.Value > 3000 AND Fields!TOTAL.Value > 3000 ,"Red")

#Aditi Singh we are on the correct track, have a look at images below, let me know your thoughts:

#SuperSimmer44 Below is the link image for the desried Output-
Drilldown Report sampleScenario: Circle>4000(Red), Zone>3000(Red), Cluster>500(Red)

Try this method (you will need to extend to hour value 10+):
=switch(Fields!HOUR1.Value = "1" and Fields!TOTAL.Value >= "100", "RED",
Fields!HOUR1.Value = "2" and Fields!TOTAL.Value >= "200", "RED",
Fields!HOUR1.Value = "3" and Fields!TOTAL.Value >= "300", "RED",
Fields!HOUR1.Value = "4" and Fields!TOTAL.Value >= "400", "RED",
Fields!HOUR1.Value = "5" and Fields!TOTAL.Value >= "500", "RED",
Fields!HOUR1.Value = "6" and Fields!TOTAL.Value >= "600", "RED",
Fields!HOUR1.Value = "7" and Fields!TOTAL.Value >= "700", "RED",
Fields!HOUR1.Value = "8" and Fields!TOTAL.Value >= "800", "RED",
Fields!HOUR1.Value = "9" and Fields!TOTAL.Value >= "900", "RED",
)

Related

Select date range into different column

Name
Date
Score
A
01-01-2023
100
A
01-01-2023
200
A
03-01-2023
300
B
02-01-2023
400
B
03-01-2023
100
B
03-01-2023
100
i have this table and i want to seperate it into multiple column of date and SUM the score on that date using Query Builder laravel or Raw SQL so it become like :
Name
Day 1
Day 2
Day 3
A
300
0
300
B
0
400
200
all of this is upto the current month so january until 31 and so on
You aren't providing anything like your attempted query, how you are passing the date ( it is a range, month only etc ), and your desired json ouput.
its hard to even assume how you are going to do things specially you are passing a column value as column name in your desired result (which doesn't make much sense with raw sql query unless those columns
aren't dynamic).
but to give you a starting point, you can simply group them by name, then date, then do another grouping by date in the collection
e.i;
$result = DB::table('table_name')->select([
'name',
'date',
])
->selectRaw('sum(score) AS score')
->groupBy(['name', 'date'])->get();
return $result->groupBy('date');
then you should be able to get result in a format like below;
{
"01-01-2023" : [
{
"name": "A",
"date": "01-01-2023",
"score": "300"
}
],
"02-01-2023" : [
{
"name": "A",
"date": "02-01-2023",
"score": "300"
}
{
"name": "B",
"date": "02-01-2023",
"score": "200"
}
],
"03-01-2023" : [
.
.
.
]
}
For you desired table result, thats better be changed to a dynamic rows instead of dynamic column
EDIT
In reference with Karl answer, you can loop through a date range and inject additional select statement.
e.i. current month dates
$dateRange = \Carbon\CarbonPeriod::create(now()->startOfMonth(), now()->endOfMonth() )->toArray();
$result = DB::table('table_name')->select(['name']);
foreach ($dateRange as $date) {
$dateFormat = $date->format('d-m-Y');
$day = $date->format('j');
$result->selectRaw("SUM(CASE WHEN Date = '$dateFormat' THEN Score ELSE 0 END) AS 'Day $day'");
}
return $result->groupBy('name')->get();
just to keep date in group by
->groupBy('date');

Create sum of Elements that are not grouped by

I'm trying to sum up all values from the values column by the timestamp "ts".
What I got so far:
select ts, item, value
from statistics
where indicator = "something"
actual:
"1", "item1", "100"
"1", "item2", "200"
"1", "item3", "300"
"2", "item1", "101"
"2", "item2", "202"
"2", "item3", "303"
expected:
"1", "item1", "100"
"1", "item2", "200"
"1", "item3", "300"
"1", "sum", "600"
"2", "item1", "101"
"2", "item2", "202"
"2", "item3", "303"
"2", "sum", "606"
Use GROUP BY and WITH ROLLUP.
select ts, item, SUM(value)
from statistics
where indicator = "something"
GROUP BY ts, item WITH ROLLUP
You have to group by both columns to get the original rows in the result, then WITH ROLLUP adds the total lines. This will add a row with item = NULL for the ts totals, and a row at the end with both ts = NULL, item = NULL for the grand total.
I think Barmar's solution should be accepted, but just for the sake of giving an alternative solution, I would describe this one:
select ts, item, value
from
(
(
select ts as ts, item, value
from statistics
where indicator = "something"
)
union
(
select ts as ts, 'zzzz_sum' as item, count(*) as value
from statistics
group by ts
)
) t
order by ts, item;
We basically union two result sets and order them accordingly

Multiple nested iif statement in Access

I am trying to calculate the number of vacation week an employee is entitled to using their years of service, with these categories:
0-4 years = 2 weeks
5-14 years = 3 weeks
15-24 years = 4 weeks
25 and up = 5 weeks
I found some examples and tried doing a nested iif statement but keep getting an error message. Can someone tell me what I am doing wrong?
VacationWeeks: IIf([YearsInService]<=4, "2",
IIf([YearsInService]is between 5 and 14, "3",
IIf([YearsInService]is between 15 and 24, "4",
IIf([YearsInService]>=25, "5", ”0”))))
You are likely receiving error messages because of two issues with your code:
A BETWEEN statement has the syntax:
expr [Not] Between value1 And value2
You should not include the word is:
IIf([YearsInService] is between 5 and 14,
^-------------------- this shouldn't be here
Your final else argument encloses the string in 'smart quotes' or Unicode character 0x201C:
IIf
(
[YearsInService] >= 25,
"5",
”0” <--- here
)
As opposed to the standard double-quote, which is Unicode/ASCII character 0x0022:
IIf
(
[YearsInService]>=25,
"5",
"0"
)
Correcting these two issues would yield an IIF statement such as:
IIf
(
[YearsInService] <= 4,
"2",
IIf
(
[YearsInService] between 5 and 14,
"3",
IIf
(
[YearsInService] between 15 and 24,
"4",
IIf
(
[YearsInService] >= 25,
"5",
"0"
)
)
)
)
However, you may find the use of a SWITCH statement more readable:
Switch
(
[YearsInService] <= 4, "2",
[YearsInService] <= 14, "3",
[YearsInService] <= 24, "4",
[YearsInService] > 24, "5",
True, "0"
)
The last test expression provides a catch-all default to account for nulls and still return a string value - I'll let you decide whether you wish to include or omit this, depending on the requirements of your application.

Calculating ranks from the following data [duplicate]

This question already has answers here:
Rank function in MySQL
(13 answers)
Closed 8 years ago.
How can I calculate the rank for all "type 10" rows in the data below using just sql?
The sql will go into a stored procedure, with no other scripting involved.
The parent holds the total of all rows in column total, and the total votes in votes.
I update the perCent col using this, so this should give you an idea. Maybe calculate ranks along with this?
All rows are linked by parent -> child relationship.
All is based on total votes and total candidates. Candidates are type 10
UPDATE likesd p
JOIN likesd h
ON p.parent = h.id
AND p.country = h.country
SET p.percent = TRUNCATE(100*p.votes/h.votes,2);
Raw Data
"id" "type" "parent" "country" "votes" "perCent" "total" "rank"
"24" "1" "1" "US" "30" "0" "" "0"
"25" "3" "24" "US" "30" "0" "3" "0"
"26" "10" "25" "US" "15" "50.00" "" "0"
"27" "10" "25" "US" "5" "16.66" "" "0"
"28" "10" "25" "US" "10" "33.33" "" "0"
Desired results
"id" "type" "parent" "country" "votes" "perCent" "total" "rank"
"24" "1" "1" "US" "30" "0" "" "0"
"25" "3" "24" "US" "30" "0" "3" "0"
"26" "10" "25" "US" "15" "50.00" "" "1" // Rank 1. Has 15 votes out of 30 (see parent row above)
"27" "10" "25" "US" "5" "16.66" "" "3" // And so on.
"28" "10" "25" "US" "10" "33.33" "" "2"
SELECT id,type,parent,country,votes,perCent,total, FIND_IN_SET( votes, (
SELECT GROUP_CONCAT( votes
ORDER BY votes DESC )
FROM table WHERE type=10 )
) AS rank
FROM table
SQL Fiddle
SQL Fiddle
UPDATE scores SET rank= (FIND_IN_SET(votes, (
SELECT * FROM(SELECT GROUP_CONCAT( votes
ORDER BY votes DESC )
FROM scores WHERE type=10)x ) ) )

mysql rename column values after select and average

In my current table i am trying to get average of columns based on comp_name and below is the output
"Comp_Name" "No_of_Rows" "Column1_Avg" "Column2_Avg" "Column3_Avg"
"Company1 Pty Ltd" "291" "39" "60" "0"
"Company1 Pty." "1699" "23" "76" "0"
"Company2 Ltd" 14335" "6" "82" "10"
"Company2 " "4335" "60" "8" "2"
"Company3 Pty Ltd" "767" "22" "77" "0"
"Company3" "1628" "16" "82" "1"
Is is possible to average "Company1 Pty Ltd" and "Company1 Pty." (and for the other companies) but add the number of rows?
My select query is below and basically it is calculating average based on a certain value and grouping based on the company name available in the table
SELECT Comp_Name,count(*) as No_of_Rows,
CAST( (COUNT(CASE WHEN Column1 < 500 then 1 else NULL end)/COUNT(mytable.ID)) * 100 AS CHAR(2))+'%' as Column1_Avg,
CAST( (COUNT(CASE WHEN (Column1 < 30000 AND Column1 > 500) then 1 else NULL end)/COUNT(mytable.ID)) * 100 AS CHAR(2))+'%' as Column2_Avg,
CAST( (COUNT(CASE WHEN (Column1 > 30000) then 1 else NULL end)/COUNT(mytable.ID)) * 100 AS CHAR(2))+'%' as Column3_Avg
FROM mytable
GROUP BY Comp_Name desc
Expected output:
"Comp_Name" "No_of_Rows" "Column1_Avg" "Column2_Avg" "Column3_Avg"
"Company1" "1990" "31" "68" "0"
"Company2" "18670" ".." ".." "6"
"Company3" "2395" ".." ".." ".."
Can i use some sort of reference table with a list of company_name and it's substitution?
If you want to only take the first word in your GROUP BY clause, you can use:
GROUP BY CASE LOCATE(' ', Comp_Name) WHEN 0 THEN Comp_Name ELSE LEFT(Comp_Name, LOCATE(' ', Comp_Name)) END
Then, if you want to build a reference table, a query like this should be fine:
SELECT DISTINCT Comp_Name, CASE LOCATE(' ', Comp_Name) WHEN 0 THEN Comp_Name ELSE LEFT(Comp_Name, LOCATE(' ', Comp_Name)) END AS Simple_Comp_Name
FROM mytable
ORDER BY Simple_Comp_Name