Please How to fix "Invalid use of group function" - mysql

I try to use nested CASE WHEN syntax in SUM() function but nothings works since 3 days
When I retrieve all sum and nested conditions the code work great
I explain:
Table contrat: Each client have a contract in which this two values: Prix_TTC (the price of the article), Qac_cont (The quantity of the article client must consume each month)
Table commande: Each client order article with quantity (Quantite_cmd)
So what I try to do is to get all financial loss for each client during the actual month and SUM all these amount
SELECT
SUM(pertes) AS pertes_reelles
FROM
(SELECT
c.ID_clt,
SUM(CASE
WHEN
((co.Qac_cont - SUM(CASE
WHEN Quantite_cmd IS NULL THEN 0
ELSE Quantite_cmd
END)) * - 1) < 0
THEN
((co.Qac_cont - SUM(CASE
WHEN Quantite_cmd IS NULL THEN 0
ELSE Quantite_cmd
END)) * - 1)
ELSE 0
END) * co.Prix_TTC AS pertes
FROM
clients c
LEFT JOIN contrat co ON co.clt_ID = c.ID_clt
LEFT JOIN commande cmd ON cmd.clt_ID = c.ID_clt
AND MONTH(DATE(cmd.date_livr_cmd)) = MONTH(DATE('2019-08-30 09:23:23'))
WHERE
c.Etat_clt <> 'D'
GROUP BY c.ID_clt) AS liste

Like #BobJarvis says, the problem was with the nested SUM so I have broken down nested processing and it WORKS Thanks ! the new request :
SELECT SUM(CASE
WHEN
perte < 0
THEN
perte * - 1
ELSE 0
END) AS pertes_reelles
FROM
(SELECT
c.ID_clt, co.Prix_TTC, ((co.Qac_cont - SUM(CASE
WHEN Quantite_cmd IS NULL THEN 0
ELSE Quantite_cmd
END)) * - 1) as ecart, co.Prix_TTC * ((co.Qac_cont - SUM(CASE
WHEN Quantite_cmd IS NULL THEN 0
ELSE Quantite_cmd
END)) * - 1) as perte
FROM
clients c
LEFT JOIN contrat co ON co.clt_ID = c.ID_clt
LEFT JOIN commande cmd ON cmd.clt_ID = c.ID_clt
AND MONTH(DATE(cmd.date_livr_cmd)) = MONTH(DATE('".$today."'))
WHERE
c.Etat_clt <> 'D'
GROUP BY c.ID_clt) AS liste

Related

SUM CASE adding from joined table instead main table

I have a query that retrieves from a customer:
sum of time expent on his tickets (every ticket can have 1 or more interventions)
average resolution time
category of each ticket
The query:
SELECT SUM(f.duree) as total_time, SUM(timestampdiff(second, t.datec, t.date_close))/COUNT(distinct t.rowid) as average_resolution, COUNT(distinct t.rowid) as tickets,
SUM( CASE t.category_code WHEN 'WITHOUT_MAINTENANCE' THEN 1 ELSE 0 END) as sin_mantenimiento,
SUM( CASE t.category_code WHEN 'WITH_MAINTENANCE' THEN 1 ELSE 0 END) as con_mantenimiento,
SUM( CASE t.category_code WHEN 'WITH_BILLABLE_MAINTENANCE' THEN 1 ELSE 0 END) as con_mantenimiento_facturable,
SUM( CASE t.category_code WHEN 'NO_BILLABLE_COASER_WARRANTY' THEN 1 ELSE 0 END) as no_facturable_garantia_coaser,
SUM( CASE t.category_code WHEN 'OFERTADO' THEN 1 ELSE 0 END) as ofertado
FROM llx_ticketsup as t
JOIN llx_element_element as ee on ee.fk_source = t.rowid
JOIN llx_fichinter as f on f.rowid = ee.fk_target
WHERE t.fk_soc = 47 AND t.fk_statut = 8
where
llx_ticketsup is main tickets table
llx_fichinter is table where interventions from tickets are stored
llx_element_element is table between tickets and interventions
My problem is, if one ticket has more than 1 intervention, on sum of category types to know how many are from this category and how many from the other, it sums interventions instead tickets. For example, if query returns 2 tickets and they have a total of 6 interventions, it returns 6 tickets of category WITHOUT_MAINTENANCE, instead 2 tickets of category WITHOUT_MAINTENANCE.
Whats wrong? Thanks.
Nothings 'wrong' that's expected behaviour try using a sub query to get the duration. Something like
SELECT (select sum(f.duree) from llx_fichinter as f on f.rowid = ee.fk_target) as total_time, SUM(timestampdiff(second, t.datec, t.date_close))/COUNT(distinct t.rowid) as average_resolution, COUNT(distinct t.rowid) as tickets,
SUM( CASE t.category_code WHEN 'WITHOUT_MAINTENANCE' THEN 1 ELSE 0 END) as sin_mantenimiento,
SUM( CASE t.category_code WHEN 'WITH_MAINTENANCE' THEN 1 ELSE 0 END) as con_mantenimiento,
SUM( CASE t.category_code WHEN 'WITH_BILLABLE_MAINTENANCE' THEN 1 ELSE 0 END) as con_mantenimiento_facturable,
SUM( CASE t.category_code WHEN 'NO_BILLABLE_COASER_WARRANTY' THEN 1 ELSE 0 END) as no_facturable_garantia_coaser,
SUM( CASE t.category_code WHEN 'OFERTADO' THEN 1 ELSE 0 END) as ofertado
FROM llx_ticketsup as t
JOIN llx_element_element as ee on ee.fk_source = t.rowid
WHERE t.fk_soc = 47 AND t.fk_statut = 8
If that doesn't work add sample data and expected result to the question as text so we can play with it.

SSRS calculate % of desired colums in column group in matrix

SELECT PatchPhase.PhaseName, MAX(PatchPhase.Sequence) AS seq,
PatchState.Application, PatchState.Objectname, PatchState.Jobname,
PatchState.Streamname, COUNT(*) AS Total,
PatchState.Jobdescription,
PatchState.Status, PatchState.Timestamp
FROM PatchState
INNER JOIN PatchPhase ON PatchState.Phase = PatchPhase.PhaseTech
WHERE (PatchPhase.PhaseName IN (#Phase))
AND (PatchState.Application IN (#Application)) AND (PatchState.Timestamp >= #StartDate)
AND (PatchState.Timestamp <= #EndDate)
GROUP BY PatchPhase.PhaseName, PatchState.Application, PatchState.Objectname,
PatchState.Jobname, PatchState.Streamname, PatchState.Jobdescription, PatchState.Status,
PatchState.Timestamp
ORDER BY PatchState.Application
I am working on matrix and I have column group of status which contains 3 columns (planned, running,completed). I want to sum planned+completed and divide by total column.
Total column is outside the column group.
I do find some answers but I did not get how should I use in my code
can someone please help?
Try using this to aggregate, and then use a table instead of a matrix. You will not need a column group now. As I cannot run the sql I can't promise it is perfect but perhaps you could have a little play with it if not. It should offer a guide if nothing else.
SELECT
PatchPhase.PhaseName,
MAX(PatchPhase.Sequence) AS seq,
PatchState.Application,
PatchState.Objectname,
PatchState.Jobname,
PatchState.Streamname,
PatchState.Jobdescription,
SUM(case when PatchState.Status = 'Planned' then 1 else 0 end) as 'Planned',
SUM(case when PatchState.Status = 'Running' then 1 else 0 end) as 'Running',
SUM(case when PatchState.Status = 'Completed' then 1 else 0 end) as 'Completed',
(SUM(case when PatchState.Status = 'Planned' then 1 else 0 end) + SUM(case when PatchState.Status = 'Running' then 1 else 0 end)) /
(SUM(case when PatchState.Status = 'Planned' then 1 else 0 end) + SUM(case when PatchState.Status = 'Running' then 1 else 0 end) + SUM(case when PatchState.Status = 'Completed' then 1 else 0 end)) as totalPercentage
PatchState.Timestamp
FROM
PatchState
INNER JOIN PatchPhase
ON PatchState.Phase = PatchPhase.PhaseTech
WHERE
(PatchPhase.PhaseName IN (#Phase))
AND (PatchState.Application IN (#Application))
AND (PatchState.Timestamp >= #StartDate)
AND (PatchState.Timestamp <= #EndDate)
GROUP BY
PatchPhase.PhaseName,
PatchState.Application,
PatchState.Objectname,
PatchState.Jobname,
PatchState.Streamname,
PatchState.Jobdescription,
PatchState.Status,
PatchState.Timestamp
ORDER BY
PatchState.Application
You can get a value displayed in a text box from expression =Reportitems!Textbox133.Value
instead of textbox133 in the above expression you have to give the textbox name of the textbox from which you want the value. In your case the total column

Appending data from different tables - mysql

I have the following tables Job description and Candidate.
Each job description can be related to n candidates. The candidates are obtained from different sources(a, b, c d) - candidate.source.
I want a single query to list me the JD ids, with count of candidates for each source for each JD, as shown below:
JD id | candidate name | count of candidates - source a | count of candidates - source b | count of candidates - source | c..............
Try using the query as a template:
select
JobDescriptionName,
SUM(ACount) CountOfCandidatesOfA ,
SUM(BCount) CountOfCandidatesOfB,
SUM(CCount) CountOfCandidatesOfC ,
SUM(DCount) CountOfCandidatesOfD
from
( select JobDescriptionID, (CASE WHEN Source = 'a' THEN 1 ELSE 0 END) AS ACount,
(CASE WHEN Source = 'b' THEN 1 ELSE 0 END) AS BCount,
(CASE WHEN Source = 'c' THEN 1 ELSE 0 END) AS CCount,
(CASE WHEN Source = 'd' THEN 1 ELSE 0 END) AS DCount
from Candidate) AS DerivedCandidate
inner join JobDescription ON JobDescription.JobDescriptionID = DerivedCandidate.JobDescriptionID group by JobDescriptionID;
I know there is already an accepted answer but in the effort of learning myself more about SQL here is an alternative way applying the case directly in the initial select without the sub-select:
Select
jd.id,
jd.name,
sum(case when c.source = 'a' then 1 else 0 end) as sourceA,
sum(case when c.source = 'b' then 1 else 0 end) as sourceB,
sum(case when c.source = 'c' then 1 else 0 end) as sourceC,
sum(case when c.source = 'd' then 1 else 0 end) as sourceD
from JobDescription as jd
join Candidate as c on c.jobId = jd.id
group by jd.id, jd.name
SQL Fiddle Demo
SELECT JD id, COUNT(Candidate), source
FROM table1
GROUP BY JD id,source

mysql sum case not working

I am working on a mysql query using sum case. The query works for some of the cases but not for one case.
select orders.orderid, campers.description, dealers.name, orders.act_delivery,
sum(case orderitems.std
when 0 then
(case when orderitems.price = 0 then retail_price.price * orderitems. qty else orderitems.price * orderitems.qty end)
when 1 then
(case when orderitems.origqty = 0 then
0 else
(case when orderitems.price = 0
then retail_price.price * (orderitems.qty - orderitems.origqty)
else orderitems.price * (orderitems.qty - orderitems.origqty)
end)
end)
when 2 then
0
else
(case when orderitems.deletedprice = 0 then retail_price.price * orderitems. qty else orderitems.deletedprice * orderitems.qty end)
end) as retail
from orderitems, orders, dealers, campers, products, retail_price
where orderitems.orderid = orders.orderid
and orderitems.productid = products.prodid
and orderitems.productid =retail_price.prodid
and orders.dealerid = retail_price.dealer
and orders.dealerid = dealers.dealerid
and orders.camper = campers.camperid
and act_delivery > 0
and orderitems.std in (0, 1, 2)
and orders.dealerid not in (1, 9, 10, 12,15,16)
and spares_od = 0
and orders.act_delivery > '2016-10-01'
and orders.act_delivery <= '2016-10-31'
group by orders.orderid,orders.dealerid, orders.act_delivery order by orders.act_delivery, orders.orderid
The problem occurs when orderitems.std = 3. In either case I cannot get a result.
All other cases appear to be working correctly.

MySQL using Sum and Case

I'm trying to create a GridView with ASP.NET connecting to a MySQL database. The data appears like below.
BusinessUnit OrderDate Canceled
UnitA 1/15/2013 N
UnitA 10/1/2013 N
UnitB 10/15/2013 N
UnitB 10/22/2013 N
UnitB 10/22/2013 N
Based on the records above, I'd like the result to appear like below
BusinessUnit TodaysOrders ThisMonthsOrders ThisYearsOrders
UnitA 0 1 2
UnitB 2 3 3
My current code is below. It's giving me error (something about DatabaseName.sum does not exist. Check the
Function Name Parsing and Resolution' section... )
Select
SUM (CASE WHEN (OrderDate)=DATE(NOW()) THEN 1 ELSE 0 END) AS TodaysOrders,
SUM (CASE WHEN YEAR(OrderDate) = YEAR(CURDATE()) AND MONTH(OrderDate) = MONTH(CURDATE()) THEN 1 ELSE 0 END) AS ThisMonthsOrders,
SUM (CASE WHEN YEAR(main_order_managers.creation_date) = YEAR(CURDATE()) THEN 1 ELSE 0 END) AS ThisYearsOrders
code continues
FROM OrderTable WHERE OrderTable.Canceled. <> 'Y';
Is Sum Case the best use here?
The error is caused by the space between function name and parenthesis
SUM (CASE WHEN ...
^^
Read more Function Name Parsing and Resolution
Try
SELECT BusinessUnit,
SUM(CASE WHEN OrderDate = CURDATE() THEN 1 ELSE 0 END) TodaysOrders,
SUM(CASE WHEN DATE_FORMAT(OrderDate, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m') THEN 1 ELSE 0 END) ThisMonthsOrders,
SUM(CASE WHEN YEAR(OrderDate) = YEAR(CURDATE()) THEN 1 ELSE 0 END) ThisYearsOrders
FROM OrderTable
WHERE Canceled <> 'Y'
GROUP BY BusinessUnit
Here is SQLFiddle demo