SSRS expression to calculate total based on daily counts that have conditions - reporting-services

In a totals row (location is row group, date is the column group), I'm not sure how to calculate a total based on the below expression that I've been using to calculate "overcapacity" daily totals. I'm trying to total up the daily overcap counts.
The below expression works fine when grouped under the "date" column grouping. So each day in the range picked by the user displays with an "overcapacity" count (if the visitscounts > 7, then the result is visitscounts - 7, otherwise it is 0).
But I'm not sure how to total up the resultant overcapacity counts (I can total up visitcounts fine). The issue is that it takes the FULL daily count and THEN applies the -7, instead of just summing all the previously calculated daily counts (if the daily account exceeds 7, then it subtracts 7 from the full daily count, to come up with an "overcapacity" count).
=IIF(SUM(IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4",Fields!VisitsCount.Value,0)) > 7,
SUM(SUM(IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4",Fields!VisitsCount.Value,0))-7),
0)
ADDITIONAL INFORMATION
Dataset Query:
SELECT
L.Location
, D.[date]
, COUNT(DISTINCT CAST(V.VisitID AS VARCHAR(10))+V.Location+V.[Room-Bed]) AS VisitsCount
FROM dbo.DateTable(#StartDate, #EndDate) AS D
CROSS JOIN (
SELECT DISTINCT Location FROM dbo.vHIMOverFlowBedReport2)
AS L LEFT JOIN dbo.vHIMOverFlowBedReport2 AS V ON D.[date] BETWEEN
V.EffectiveDate AND ISNULL(V.ServiceEndDate, #EndDate) AND V.Location = L.Location
WHERE V.EffectiveDate IS NULL OR
(V.EffectiveDate <= #EndDate OR
V.ServiceEndDate >= #StartDate OR
V.ServiceEndDate IS NULL)
GROUP BY
L.Location
, D.[date]
ORDER BY L.Location, D.[date]
OverCap New Column Testing
Dataset Query with Added OverCap Column:
SELECT
x.Location
, x.[date]
, x.VisitsCount
, OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
FROM (
SELECT
L.Location
, D.[date]
, COUNT(DISTINCT CAST(V.VisitID AS VARCHAR(10))+V.Location+V.[Room-Bed]) AS VisitsCount
FROM dbo.DateTable(#StartDate, #EndDate) AS D
CROSS JOIN (
SELECT DISTINCT Location FROM dbo.vHIMOverFlowBedReport2)
AS L LEFT JOIN dbo.vHIMOverFlowBedReport2 AS V ON D.[date] BETWEEN
V.EffectiveDate AND ISNULL(V.ServiceEndDate, #EndDate) AND V.Location = L.Location
WHERE V.EffectiveDate IS NULL OR
(V.EffectiveDate <= #EndDate OR
V.ServiceEndDate >= #StartDate OR
V.ServiceEndDate IS NULL)
GROUP BY
L.Location
, D.[date]
) x
ORDER BY x.Location, x.[date]
Full Report Layout with OverCap added
Grouped by Location (row) and [date] (column), with a totals row outside row group for combined location.
report layout
Current Resultset with OverCap Column
CurrentResultSet
NOTES:
Result for LOC3-4 is 129 (see CurrentResultSet) if I use:
OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
Result for LOC3-4 is 34 if I use:
OverCap = IIF(Location = 'LOC3' OR Location = 'LOC4', VisitsCount,0)
Result for LOC3-4 is 24 if I use:
OverCap = IIF((Location = 'LOC3' OR Location = 'LOC4') AND VisitsCount > 7, VisitsCount,0)
Expressions Used Successfully for GROUPED locations:
DailyVisitorCount (used for both DailyVisitorCount and TotalVisitorCount).
=Sum(Fields!VisitsCount.Value)
DailyOverCapacityCount (used for both DailyOverCapacityCount and TotalOverCapacityCount):
=SWITCH(
Fields!Location.Value = "LOC1" AND Fields!VisitsCount.Value > 24, SUM(Fields!VisitsCount.Value - 24),
Fields!Location.Value = "LOC2" AND Fields!VisitsCount.Value > 16, SUM(Fields!VisitsCount.Value - 16),
Fields!Location.Value = "LOC3" AND Fields!VisitsCount.Value > 7, SUM(Fields!VisitsCount.Value - 7),
Fields!Location.Value = "LOC4" AND Fields!VisitsCount.Value > 7, SUM(Fields!VisitsCount.Value - 7),
Fields!Location.Value = "LOC5" AND Fields!VisitsCount.Value > 11, SUM(Fields!VisitsCount.Value - 11),
True, 0)
Averages were calculated by using the above expressions but adding to the end:
/CountDistinct(Fields!date.Value)
Expressions Used for combined location (outside grouped location row)
DailyVisitorCount (used successfully for both DailyVisitorCount and TotalVisitorCount).
=IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4", Sum(Fields!VisitsCount.Value), 0)
TotalOverCapCount (used successfully with DAILY TotalOverCapCount, but not the Total TotalOverCapCount
=IIF(SUM(IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4",Fields!VisitsCount.Value,0)) > 7,
SUM(SUM(IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4",Fields!VisitsCount.Value,0))-7),
0)
Expressions still needed:
Total TotalOverCapCount (adds up daily totals for the duration)
Average TotalOverCapCount (average of daily totals for the duration)

As the expression you are trying to sum requires two scoped expression parts, it's actually difficult to then sum these.
What you need to do is
=SUM(
SUM(Fields!.MyField.Value, "ColumnGroup")
, "RowGroup")
This is probably not possible in your scenario. I abandoned the approach quickly and just updated the dataset query to return the data I needed instead
So the dataset query looked like this (using you sample data)
DECLARE #t TABLE([Location] varchar(10), [Date] Date, [VisitsCount] int)
INSERT INTO #t VALUES
('LOC1', '2022-10-31', 18), ('LOC1', '2022-11-01', 19),
('LOC1', '2022-11-02', 19), ('LOC2', '2022-10-31', 34),
('LOC2', '2022-11-01', 30), ('LOC2', '2022-11-02', 35),
('LOC3', '2022-10-31', 8), ('LOC3', '2022-11-01', 8),
('LOC3', '2022-11-02', 8), ('LOC4', '2022-10-31', 5),
('LOC4', '2022-11-01', 5), ('LOC4', '2022-11-02', 7),
('LOC5', '2022-10-31', 11), ('LOC5', '2022-11-01', 11),
('LOC5', '2022-11-02', 11)
SELECT
[Location], [Date], VisitsCount
, OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
FROM #t
As you can see, I added an OverCap column. Now all we need to do is sum that in the report.
The report design looks like this..
and the final report looks like this...
Obviously you might need to adapt this to suit whatever grouping you have going but I think it's probably a much simpler approach.
Edit after update by OP
You can wrap your original query in a SELECT and then move the order clause of of the sub query. That should give you the same results.
SELECT
[Location], [Date], VisitsCount
, OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
FROM (
SELECT
L.Location
, D.[date]
, COUNT(DISTINCT CAST(V.VisitID AS VARCHAR(10))+V.Location+V.[Room-Bed]) AS VisitsCount
FROM dbo.DateTable(#StartDate, #EndDate) AS D
CROSS JOIN (
SELECT DISTINCT Location FROM dbo.vHIMOverFlowBedReport2)
AS L LEFT JOIN dbo.vHIMOverFlowBedReport2 AS V ON D.[date] BETWEEN
V.EffectiveDate AND ISNULL(V.ServiceEndDate, #EndDate) AND V.Location = L.Location
WHERE V.EffectiveDate IS NULL OR
(V.EffectiveDate <= #EndDate OR
V.ServiceEndDate >= #StartDate OR
V.ServiceEndDate IS NULL)
GROUP BY
L.Location
, D.[date]
) x
ORDER BY [Location], [date]
If you want to just get LOC3+4 at the end of the table
Then you can do this in SQL. All I've done here is taken the existing query, dumped the results to a temp table , then returned the results plus an extra row that only contains LOC3 and LOC4 data.
Note: I added a GroupOrder column so you can sort on this in the report to make sure the combined row appears at the end.
SELECT
[Location], [Date], VisitsCount
, OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
INTO #t
FROM (
SELECT
L.Location
, D.[date]
, COUNT(DISTINCT CAST(V.VisitID AS VARCHAR(10))+V.Location+V.[Room-Bed]) AS VisitsCount
FROM dbo.DateTable(#StartDate, #EndDate) AS D
CROSS JOIN (
SELECT DISTINCT Location FROM dbo.vHIMOverFlowBedReport2)
AS L LEFT JOIN dbo.vHIMOverFlowBedReport2 AS V ON D.[date] BETWEEN
V.EffectiveDate AND ISNULL(V.ServiceEndDate, #EndDate) AND V.Location = L.Location
WHERE V.EffectiveDate IS NULL OR
(V.EffectiveDate <= #EndDate OR
V.ServiceEndDate >= #StartDate OR
V.ServiceEndDate IS NULL)
GROUP BY
L.Location
, D.[date]
) x
SELECT
GroupOrder = 1
, [Location], [Date], VisitsCount, OverCap
FROM #t
UNION ALL
SELECT
GroupOrder = 2
, [Location] = 'LOC3+4', MIN([Date]), SUM(VisitsCount), SUM(OverCap)
FROM #t
WHERE [Location] IN ('LOC3', 'LOC4')
GROUP BY YEAR([Date]), MONTH([Date])

Related

MySQL help making query

I need to display the consumption of products for 6 months.
My table Consumption is made as:
int ID_Conso
int ID_Product
int Quantity_Conso
int Month_Conso
int Year_COnso
there is 1 record/1 product/1 month as shown in picture below
the query I want to write for my view must show the result as :
Here is my query :
SELECT c.id_Product,
t1.conso1,
t2.conso2,
t3.conso3,
t4.conso4,
t5.conso5,
t6.conso6
FROM Consumption c,
(SELECT quantity_conso as "conso1"
FROM `consumption`
WHERE year= Year(Now()) and month = 1) t1,
(SELECT quantity_conso as "conso2"
FROM `consumption`
WHERE year= Year(Now()) and month = 2) t2,
(SELECT quantity_conso as "conso3"
FROM `consumption`
WHERE year= Year(Now()) and month = 3) t3,
(SELECT quantity_conso as "conso4"
FROM `consumption`
WHERE year= Year(Now()) and month = 4) t4,
(SELECT quantity_conso as "conso5"
FROM `consumption`
WHERE year= Year(Now()) and month = 5) t5,
(SELECT quantity_conso as "conso6"
FROM `consumption`
WHERE year= Year(Now()) and month = 6) t6
this query displays all the records for all the id_product (doesn't display null if one record is missing)
I have tried to use if exist but without success.
Use aggregation function SUM with IF, and GROUP BY on Id_Product. Try the following query:
SELECT
Id_Product,
SUM(IF(Month_Conso = 1, Quantity_Conso, 0)) AS QtyConso_Month1,
SUM(IF(Month_Conso = 2, Quantity_Conso, 0)) AS QtyConso_Month2,
SUM(IF(Month_Conso = 3, Quantity_Conso, 0)) AS QtyConso_Month3,
SUM(IF(Month_Conso = 4, Quantity_Conso, 0)) AS QtyConso_Month4,
SUM(IF(Month_Conso = 5, Quantity_Conso, 0)) AS QtyConso_Month5,
SUM(IF(Month_Conso = 6, Quantity_Conso, 0)) AS QtyConso_Month6
FROM Consumption
GROUP BY Id_Product
ORDER BY Id_Product ASC

SSRS Predicament with expressions

I have an SSRS dataset that looks like this:
The dataset rows are generated independent of each other using UNION ALL.
I need to display these rows in my report as is, but I need to add an additional row that will calculate Total Won / Total Lost, so the result should look like this:
This is just sample as I have more columns (1 per month) and the whole thing is broken down by product, so if I have 10 different products, I will have 10 different tablix tables.
Basically I need to somehow create an expression that will only calculate values in 2 rows of the tablix out of 3 (based on the value of the Status column) and take into consideration that some values can be zeroes.
Here's the query (I simplified it a bit for better understanding):
select * from
(
select 'Created' as 'State', fo.groupidname, fo.businessidname ' Business', fo.opportunityid
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.createdon >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
) created
pivot
(
count(created.opportunityid)
for created.groupidname in ([Boston], [Chicago], [Colombia], [Group D.C.], [Houston], [Los Angeles], [New York], [San Francisco], [Seattle], [Toronto])
) pivCreated
union all
select * from
(
select 'Won' as 'State', fo.groupidname, fo.businessidname ' Business', fo.opportunityid
from FilteredOpportunity fo
where regionidname = 'Americas Region'
and fo.actualclosedate >= dateadd(year, -1, getdate())
and regionalfeeincome >= 250000
and fo.jna is not null
) won
pivot
(
count(won.opportunityid)
for won.groupidname in ([Boston], [Chicago], [Colombia], [Group D.C.], [Houston], [Los Angeles], [New York], [San Francisco], [Seattle], [Toronto])
) pivWon
union all
select * from
(
select 'Lost' as 'State', fo.groupidname, fo.businessidname ' Business', fo.opportunityid
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.actualclosedate >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
and fo.sys_phasename <> 'Pre-Bid'
) lost
pivot
(
count(lost.opportunityid)
for lost.groupidname in ([Boston], [Chicago], [Colombia], [Group D.C.], [Houston], [Los Angeles], [New York], [San Francisco], [Seattle], [Toronto])
) pivLost
TIA
-TS.
I can't fully test this as I don't have time to build sample data but it should work...
If you use this as your report's dataset query then you should be able to add a simple matrix with a row group by State and a column group by City
/*
You can optimise this a bit but I've kept it fairly procedural so it's easier to follow
*/
-- First do your 3 basic queries but this time we don't pivot and we dump the results into temp tables
-- I've also removed columns that don't appear to be used based on your sample output and remaned a column to City to make it easier to read
select 'Total Created' as 'State', fo.groupidname as City, COUNT(*) AS Cnt
INTO #Created
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.createdon >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
select 'Total Won' as 'State', fo.groupidname as City, COUNT(*) AS Cnt
INTO #Won
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.createdon >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
and fo.jna is not null
select 'Total Lost' as 'State', fo.groupidname as City, COUNT(*) AS Cnt
INTO #Lost
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.createdon >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
and fo.sys_phasename <> 'Pre-Bid'
-- Now we calculate your Ratio
SELECT
'Win Ratio' as 'State'
, coalesce(w.City, l.City) as City -- use coalesce in case 1 side of join is null
, CASE WHEN ISNULL(l.cnt,0) = 0 THEN 0 ELSE w.Cnt/l.Cnt END as Cnt -- if lost is null or 0 return 0 else calc ratio
into #Ratio
FROM #Won w
full join #Lost l on w.City = l.City
-- finaly, get the results and add a sort to help the report row sorting.
SELECT 1 as Sort, * FROM #Created
UNION SELECT 2, * FROM #Won
UNION SELECT 3, * FROM #Lost
UNION SELECT 4, * FROM #Ratio

SQL Query Issue - Picking the minimum time when there is a maximum number

SQL God...I need some help!
I have a data table that has a route_complete_percentage column and a created_at column.
I need two pieces of data:
the time stamp (within created_at column) when the route_complete_percentage is at its minimum but not zero
the time stamp (within created_at column) when the route_complete_percentage is at its maximum, it might be 100% or not, but when its at its highest.
Here is the kicker, there might be multiple time stamps for the highest route completion column. For example,
Example Table
I have multiple values when the route_completion_percentage is at its maximum, but I need the minimum time stamp value.
Here is the query so far...but the two time stamps are the same.
SELECT
A.fc,
A.plan_id,
A.route_id,
mintime.first_scan AS First_Batch_Scan,
min(route_complete_percentage),
maxtime.last_scan AS Last_Batch_Scan,
max(route_complete_percentage)
FROM
(SELECT
fc,
plan_id,
route_id,
route_complete_percentage,
CONCAT(plan_id, '-', route_id) AS JOINKEY
FROM
houdini_ops.BATCHINATOR_SCAN_LOGS_V2
WHERE
fc <> ''
AND order_id <> 'Can\'t find order'
AND source = 'scan'
AND created_at > DATE_ADD(CURDATE(), INTERVAL - 3 DAY)) A
LEFT JOIN
(SELECT
l.fc,
l.route_id,
l.plan_id,
CONCAT(l.plan_id, '-', l.route_id) AS JOINKEY,
CASE
WHEN MIN(route_complete_percentage) THEN CONVERT_TZ(l.created_at, 'UTC', s.time_zone)
END AS first_scan
FROM
houdini_ops.BATCHINATOR_SCAN_LOGS_V2 l
JOIN houdini_ops.O_SERVICE_AREA_ATTRIBUTES s ON l.fc = s.default_station_code
WHERE
l.fc <> ''
AND l.order_id <> 'Can\'t find order'
AND l.source = 'scan'
AND l.created_at > DATE_ADD(CURDATE(), INTERVAL - 3 DAY)
GROUP BY fc , plan_id , route_id) mintime ON A.JOINKEY = mintime.JOINKEY
LEFT JOIN
(SELECT
l.fc,
l.route_id,
l.plan_id,
CONCAT(l.plan_id, '-', l.route_id) AS JOINKEY,
CASE
WHEN MAX(route_complete_percentage) THEN CONVERT_TZ(l.created_at, 'UTC', s.time_zone)
END AS last_scan
FROM
houdini_ops.BATCHINATOR_SCAN_LOGS_V2 l
JOIN houdini_ops.O_SERVICE_AREA_ATTRIBUTES s ON l.fc = s.default_station_code
WHERE
l.fc <> ''
AND l.order_id <> 'Can\'t find order'
AND l.source = 'scan'
AND l.created_at > DATE_ADD(CURDATE(), INTERVAL - 3 DAY)
GROUP BY fc , plan_id , route_id) maxtime ON mintime.JOINKEY = maxtime.JOINKEY
GROUP BY fc , plan_id , route_id
I don't want to meddle with the rest of your query. Here is something that will do what it sounds like you need. There's sample data included. -- I interpreted your blank values as nulls from your sample data.
Basically, what you are looking for is the Minimum created_at value, inside each of the route_complete_percentage groups. So I treated route_complete_percentage as a group identifier. But you only care about two of the groups, so I identify those groups first in the cte, and use them to filter the aggregate query.
if object_id('tempdb.dbo.#Data') is not null drop table #Data
go
create table #Data (
route_complete_percentage int,
created_at datetime
)
insert into #Data (route_complete_percentage, created_at)
values
(0, '20170531 19:58'),
(1, null),
(2, null),
(3, null),
(4, null),
(5, null),
(6, null),
(7, null),
(80, null),
(90, null),
(100, '20170531 20:10'),
(100, '20170531 20:12'),
(100, '20170531 20:15')
;with cteMinMax(min_route_complete_percentage, max_route_complete_percentage) as (
select
min(route_complete_percentage),
max(route_complete_percentage)
from #Data D
-- This ensures the condition that you don't get the timestamp for 0
where D.route_complete_percentage > 0
)
select
route_complete_percentage,
min_created_at = min(created_at)
from #Data D
join cteMinMax MM on D.route_complete_percentage in (MM.min_route_complete_percentage, MM.max_route_complete_percentage)
group by route_complete_percentage

SQL make 2 different date types in one query

I made a query that has 3 tables: 1 with current year, last year and name of the country
As you can see the results of current year and last year are the same and that is the problem here. I want to use like. I want to make 1 query with one that has current year and one with last year.
I can use this for last year YEAR(o.date_add) = YEAR(NOW() - INTERVAL 1 YEAR)
And from current year i can use this for example: YEAR(o.date_add) = YEAR(CURRENT_DATE())
My query:
SELECT
IFNULL(SUM(DISTINCT o.total_paid_tax_excl), 0) AS CurrentYEAR,
IFNULL(SUM(DISTINCT o.total_paid_tax_excl), 0) AS LastYEAR,
IFNULL(CONCAT(l.name), 0) AS name
FROM
expoled.ps_orders o
LEFT JOIN
expoled.ps_address a ON o.id_address_delivery = a.id_address
INNER JOIN
expoled.ps_country c ON a.id_country = c.id_country
INNER JOIN
expoled.ps_country_lang l ON c.id_country = l.id_country
WHERE
l.id_lang = 7
AND o.current_state IN (3 , 4, 5, 9, 13, 15, 20, 22, 23, 24, 25, 121)
AND l.name NOT IN ('Netherlands')
GROUP BY (l.name)
I can make seperate query but i want it in 1 query how can i archief this?
I did try Union but the results stayed the same.
I want to have it like this(this one does not work!! just for example[photoshop]
I think I need to change this part of the query
SELECT
IFNULL(SUM(o.total_paid_tax_excl), 0) AS CurrentYEAR,
IFNULL(SUM(o.total_paid_tax_excl), 0) AS LastYEAR,
IFNULL(CONCAT(l.name), 0) AS name
FROM
And add this to my query
For CurrentYEAR = YEAR(o.date_add) = YEAR(CURRENT_DATE())
For LastYEAR = YEAR(o.date_add) = YEAR(NOW() - INTERVAL 1 YEAR)
I think you can try something like this (I added CASE for fields with SUM and a Where condition to extract only relevant years):
SELECT
IFNULL(SUM( CASE WHEN YEAR(CURRENT_DATE)-YEAR(o.date_date) =0 THEN o.total_paid_tax_excl ELSE 0 END), 0) AS CurrentYEAR,
IFNULL(SUM( CASE WHEN YEAR(CURRENT_DATE)-YEAR(o.date_date) =1 THEN o.total_paid_tax_excl ELSE 0 END), 0) AS LastYEAR,
IFNULL(CONCAT(l.name), 0) AS name
FROM
expoled.ps_orders o
LEFT JOIN
expoled.ps_address a ON o.id_address_delivery = a.id_address
INNER JOIN
expoled.ps_country c ON a.id_country = c.id_country
INNER JOIN
expoled.ps_country_lang l ON c.id_country = l.id_country
WHERE
l.id_lang = 7
AND o.current_state IN (3 , 4, 5, 9, 13, 15, 20, 22, 23, 24, 25, 121)
AND l.name NOT IN ('Netherlands')
AND YEAR(o.date_date) IN (YEAR(CURRENT_DATE()), YEAR(CURRENT_DATE)-1)
GROUP BY (l.name)
You can use a conditional expression (if() function or case statement) within the sum() aggregate function to add only those values that fit the criteria:
SELECT
IFNULL(SUM(DISTINCT if(YEAR(o.date_add) = YEAR(CURRENT_DATE()),o.total_paid_tax_excl, 0)), 0) AS CurrentYEAR,
IFNULL(SUM(DISTINCT if(YEAR(o.date_add) = YEAR(CURRENT_DATE())-1,o.total_paid_tax_excl, 0)), 0) AS LastYEAR,
IFNULL(l.name, '') AS name
FROM
expoled.ps_orders o
LEFT JOIN
expoled.ps_address a ON o.id_address_delivery = a.id_address
INNER JOIN
expoled.ps_country c ON a.id_country = c.id_country
INNER JOIN
expoled.ps_country_lang l ON c.id_country = l.id_country
WHERE
l.id_lang = 7
AND o.current_state IN (3 , 4, 5, 9, 13, 15, 20, 22, 23, 24, 25, 121)
AND l.name NOT IN ('Netherlands')
GROUP BY IFNULL(l.name, '')
I also simplified the expression for the name field and made the group by clause consistent with it.
I did not change any other parts of the query, although I do not really agree with the distinct within the sum(), since you could have the same value paid as tax, but it is your data.
If your table has older data than the previous year's, then consider adding a where criteria to restrict the records for which the calculations are run.

MySQL - conditional select in group

I have a simple table with several rows and I would like to group them by id_room and select value only when condition is true. Problem is that condition is always false even there is a row with right date column year_month.
Here is schema:
CREATE TABLE tbl_account_room (
`id` int,
`year_month` date,
`value` int,
`id_room` int
);
INSERT INTO tbl_account_room
(`id`, `year_month`, `value`, `id_room`)
VALUES
(1, '2016-08-01', 1, 300),
(2, '2016-09-01', 2, 300),
(3, '2016-10-01', 3, 300);
and here query:
SELECT
(case when '2016-10-01' = ar.year_month then ar.value else 0 end) as total
FROM tbl_account_room AS ar
WHERE ar.year_month >= "2016-08-01"
AND ar.year_month <= "2016-11-01"
and ar.id_room = '300'
GROUP BY ar.id_room
LIMIT 10
Here is SQL Fiddle
In column total I'm getting 0 and I would like to get value 3 because year_month is 2016-10-01. Why this happens?
You certainly don't need that CASE condition and include that condition in your WHERE clause rather like
SELECT
ar.value as total,
GROUP_CONCAT(ar.year_month)
FROM tbl_account_room AS ar
WHERE ar.year_month = '2016-10-01'
GROUP BY ar.id_room;
Not sure why you want the result like that, here you can use self join to do that:
SELECT
MAX(t1.value) as total,
GROUP_CONCAT(ar.year_month)
FROM tbl_account_room AS ar
LEFT JOIN tbl_account_room AS t1
ON ar.id_room = t1.id_room
AND ar.year_month = t1.year_month
AND t1.year_month = '2016-10-01'
WHERE ar.year_month >= "2016-08-01"
AND ar.year_month <= "2016-11-01"
and ar.id_room = '300'
GROUP BY ar.id_room
LIMIT 10;
and here is SQLFiddle Demo.