Sub-select SUM of columns WHERE x=y - mysql

I currently have a statement along the lines of:
SELECT
SUM(claims.sanctioned_resultant) AS 'Resultant',
SUM(claims.sanctioned_flooring) AS 'Flooring',
SUM(claims.sanctioned_contents) AS 'Furniture',
etc, and I need to include a "WHERE" in this somehow. Along the lines of:
SUM(claims.sanctioned_resultant WHERE claims.a_column = 1)
Obviously this doesn't work, since SUM just.. sums. I currently have a whole other query with the WHERE claims_a_column = 1 clause, then later combine the results. The "WHERE" condition cannot be added to this query, as the majority of results won't be selected by it.
I've looked into CASE WHEN, and sub-selects, but can't figure out the actual syntax.
Full query, in case it helps:
SELECT
CONCAT(users.user_first_name,IF((users.user_surname<>''),CONCAT(' ',users.user_surname),'')) as 'Surveyor',
SUM(claims.sanctioned_roof + claims.sanctioned_building + claims.sanctioned_internal + claims.sanctioned_resultant + claims.sanctioned_flooring + claims.sanctioned_contents) AS 'Overall',
SUM(claims.sanctioned_roof) AS 'Roofing',
SUM(claims.sanctioned_building + claims.sanctioned_internal) AS 'Building',
SUM(claims.sanctioned_resultant) AS 'Resultant',
SUM(claims.sanctioned_flooring) AS 'Flooring',
SUM(claims.sanctioned_contents) AS 'Furniture',
COUNT(CASE WHEN claims.claimed_amount > 0 THEN 1 END) AS 'OverallCount',
COUNT(CASE WHEN (claims.claimed_amount > 0 AND claims.peril_id IN (" . implode(',', $WRPPerils) . ")) THEN 1 END) AS 'WRPCount',
COUNT(CASE WHEN claims.claimed_roof > 0 THEN 1 END) AS 'RoofingCount',
COUNT(CASE WHEN (claims.claimed_building > 0) OR (claims.sanctioned_internal > 0) THEN 1 END) AS 'BuildingCount',
COUNT(CASE WHEN claims.claimed_resultant > 0 THEN 1 END) AS 'ResultantCount',
COUNT(CASE WHEN claims.claimed_flooring > 0 THEN 1 END) AS 'FlooringCount',
COUNT(CASE WHEN claims.claimed_contents > 0 THEN 1 END) AS 'FurnitureCount',
COUNT(CASE WHEN claims.claimed_amount > 0 AND claims.letter_of_findings = 'Y' THEN 1 END) AS 'LOFCount'
FROM
claims claims
INNER JOIN users users ON claims.surveyor_id = users.user_id
INNER JOIN insurers insurers on claims.insurer_id = insurers.insurer_id
WHERE
(claims.claim_type <> " . $conn->qstr(TYPE_DESKTOP) . ") AND
(claims.claim_type <> " . $conn->qstr(TYPE_AUDIT) . ") AND
(claims.claim_cancelled_id <= 0) AND
(claims.date_completed BETWEEN '" . $start_date . " 00:00:00' AND '" . $end_date . " 23:59:59') AND
(claims.overturn_confirmed = 'N' OR claims.overturn_confirmed IS NULL)
GROUP BY surveyor_id

I think the easiest way to do what you want will be using a CASE statement within the SUM function itself, like this:
SUM(CASE WHEN claims.a_column = 1 THEN claims.sanctioned_resultant ELSE 0 END)

Related

Please How to fix "Invalid use of group function"

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

I have a form content like this

I have a problem when it will create a view in phpmyadmin
like this # 1349 - SELECT Views contains subqueries in the FROM clause
my coding like this please help
SELECT b.ngr_tjuan, SUM (b.LFormal) AS LFormal, SUM (b.PFormal) AS PFormal, SUM (b.LFormal) + SUM (b.PFormal) AS SUMFormal,
SUM (b.LInformal) AS LInformal, SUM (b.PInformal) AS PInformal, SUM (b.LInformal) + SUM (b.PInformal) AS SUMInformal FROM
(SELECT a.ngr_tjuan,
(CASE WHEN a.sktor_pkrjaan = 'FORMAL' AND a.jk = 'L' THEN JJK ELSE 0 END) AS LFormal,
(CASE WHEN a.sktor_pkrjaan = 'FORMAL' AND a.jk = 'P' THEN JJK ELSE 0 END) AS PFormal,
(CASE WHEN a.sktor_pkrjaan = 'INFORMAL' AND a.jk = 'L' THEN JJK ELSE 0 END) AS LInformal,
(CASE WHEN a.sktor_pkrjaan = 'INFORMAL' AND a.jk = 'P' THEN JJK ELSE 0 END) US PInformal
FROM
(SELECT ngr_tjuan, COUNT (jk) AS JJK, sktor_pkrjaan, jk
FROM tbtki2
GROUP BY ngr_tjuan, sktor_pkrjaan, jk) a
WHERE a.JJK> 0) b
GROUP BY b.ngr_tjuan

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.

Sum (case when column name then 1 else 0) always returns one row. How can I make it not return nothing

SELECT
SUM(CASE WHEN alert_header = 'Overspeeding' THEN 1 ELSE 0 END) AS overspeeding,
SUM(CASE WHEN alert_header = 'Tyre Pressure' THEN 1 ELSE 0 END) AS tyre_pressure,
itms_assets.assets_name,
fname,
lname
FROM itms_alert_master
LEFT JOIN itms_assets
ON (itms_assets.asset_id = itms_alert_master.asset_id)
LEFT JOIN itms_personnel_master
ON (itms_personnel_master.personnel_id = itms_alert_master.driver_id)
WHERE
itms_alert_master.del_date IS NULL
AND itms_alert_master.company_id = '" . $company_id . "'
I solved the problem by having a "count(*) as data_size" in query, and checking that if it is "0".

Is it possible to use SUM - CASE - IF together?

When I try to use this:
SUM(CASE WHEN IF(SUM(CASE WHEN "b.count_students_status" = 1 THEN 1 ELSE 0 END) >= 1, 1, 0) = 1 THEN 1 ELSE 0 END)
It says Query Error: Improper usage of Group Function
Below is the complete code:
SELECT
"a.batch" AS Batch,
SUM(
CASE
WHEN IF(
SUM(
CASE
WHEN "b.count_students_status" = 1
THEN 1
ELSE 0
END
) >= 1,
1,
0
) = 1
THEN 1
ELSE 0
END
) AS Payments_Not_Received
FROM
"DBU - Complete"
WHERE "a.suspended" = 'no'
GROUP BY "a.batch"
I wanted to convert the status to 1, if there are multiple occurrences and then sum the total occurrences.
Any help please - I am using ZOHO to build the query?
You're trying to reference the result of the GROUP BY before is has run. Try something like this:
select t.BATCH,
sum(case when t.pnr >=1 then 1 else 0 end) as Payments_Not_Received
from
(
select
a.batch as BATCH,
SUM(CASE WHEN "b.count_students_status" = 1 THEN 1
ELSE 0
END) as pnr
from yourTable a
WHERE a.suspended = 'no'
group by a.batch
) t
group by t.BATCH;