Multiplying CASE row with different values - mysql

I'm creating a rating system. I have two tables hinne (rating) and hinnang (rating multiplier). I need to multiply the rating and then average the rating to know what rating I got out of all ratings by aine(subject).
Example:
All points need to be calculated in 0-100 point system.
So if my first rate is 25 and the rating multiplier is 4 then first rate (25/25)
4*25=100
If the second rate is 30 and multiplier 2 then second rate (30/50)
2*30=60
Now I need to average them like 100+60/2=80.
That should work in my SQL statement, but I got in trouble.
CASE
WHEN aine.nimetus = 'Füüsika I'
THEN hinne.tulemus * hindamine.kaal
ELSE 0
END
,0)
))
So, this is my pivot case statement. hindamine.kaal should be different value for each hinne.tulemus 25*4,50*2 BUT it doesn't work. It just uses multiplier value 4. How can I make this work?
The result of SQL: 150
The expected result: 100
Therefore here is my full SQL:
SELECT
tudeng.m_number,hindamine.kaal, ROUND(AVG(NULLIF(
CASE
WHEN aine.nimetus = 'Füüsika I'
THEN hinne.tulemus * hindamine.kaal
ELSE 0
END
,0)
))
AS FüüsikaI ,ROUND(AVG(NULLIF(
CASE
WHEN aine.nimetus = 'Kõrgem matemaatika I'
THEN hinne.tulemus * hindamine.kaal
ELSE 0
END
,0)
))
AS KõrgemmatemaatikaI ,ROUND(AVG(NULLIF(
CASE
WHEN aine.nimetus = 'Raalprojekteerimine'
THEN hinne.tulemus * hindamine.kaal
ELSE 0
END
,0)
))
AS Raalprojekteerimine ,ROUND(AVG(NULLIF(
CASE
WHEN aine.nimetus = 'Tehniline graafika'
THEN hinne.tulemus * hindamine.kaal
ELSE 0
END
,0)
))
AS Tehnilinegraafika , ROUND(AVG(NULLIF(
CASE
WHEN aine.nimetus = 'Ettevõteluse alused'
THEN hinne.tulemus * hindamine.kaal
ELSE 0
END
,0)
))
AS Ettevõtelusealused
FROM
tudeng
INNER JOIN
aine_tudeng
ON
tudeng.tudeng_id = aine_tudeng.tudeng_id
INNER JOIN
aine
ON
aine.aine_id = aine_tudeng.aine_id
INNER JOIN
hinne
ON
hinne.aine_tudeng_id=aine_tudeng.aine_tudeng_id
INNER JOIN
hindamine
ON
hindamine.hindamine_id=aine_tudeng.aine_id
GROUP BY
tudeng.m_number

I suppose your error is here:
ON hindamine.hindamine_id = aine_tudeng.aine_id
A hindamine (assessment/rating?) is something different from an aine (subject?), so you are mistaken in joining on these IDs.
(I have used Google translator to help me with the meanings.)

Related

Diffrence between sum of two products > 0

I want to select the sum of T_No where Transactions are equal to R and subtract it by T_No where Transactions are equal to D and the answer of this should greater than zero for a CustomerID which would be a input (an int input declared in a stored procedure)
((Sum(T_No) where Transactions = R - Sum(T_No) where Transactions = D ) > 0) where CoustomerID = #input
Example : for ID = 1 it would be ((20+15) - 10) > 0
I Have tried so many things but either syntax is wrong, wrong value or it does not accept, and I am literally Stuck, this was my final attempt
SELECT
(select ( select Sum(T_No) where Transactions = R) - (select Sum(T_No) where Transactions = D) as C_T )
FROM CustomerTrans WHERE C_T > 0 ;
Conditional aggregation should help:
SELECT
SUM(CASE WHEN Transaction = 'R' THEN t_no ELSE 0 END) - SUM(CASE WHEN Transaction = 'D' THEN t_no ELSE 0 END)
FROM CustomerTrans
WHERE CoustomerID = #yourCustomerIdVariable
As you're writing a sproc you can assign the result of this to a variable and then decide what to do if the result is negative. (I would personally log an error for example, rather than just hide those results). If the result is null, then there were no transactions for that customer
ps; I used Transaction because that's what your screenshot showed, and I figured a screenshot is less likely to contain a typo than code with syntax errors. Adjust if required
you where kinda close, I would sum like you, only the syntax is a bit off, you can't have aggregate fields in Where, thats why you should use having, also case when syntax is not correct.
Select
CoustomerID,
Sum(case when Transactions = 'R' then T_No else 0 end) -
Sum(case when Transactions = 'D' then T_No else 0 end) as C_T
FROM CustomerTrans
group by CoustomerID
having (Sum(case when Transactions = 'R' then T_No else 0 end) -
Sum(case when Transactions = 'D' then T_No else 0 end))>0

COUNT multiple types of same column

In my current query:
SELECT COUNT(WC.ID) AS "Regions"
FROM WHOLE_FEATURES_PDB_CHAINS AS WC
;
I COUNT(WC.ID) AS "Regions" .
However, we have multiple regions with WC.Type can be 1,2,3,4. I need to count each type occurrence into COUNT(WC.ID) AS "Region_1", COUNT(WC.ID) AS "Region_2" ... depending on WC.Type.
Is there any way to solve this in one query? I am looking at MySQL IF, yet do not know how to integrate it into the count function.
I need it to be in one row (the shown query here is reduced, it's a larger query)
SELECT COUNT(WC.ID) AS "Region_1" , COUNT(WC.ID) AS "Region_2" ...
Here is the complete query if anyone is interested:
SELECT PCS.PDB_id, PCS.Chain, PPA.ENSEMBL_start, PPA.ENSEMBL_end, PPA.eValue, PIN.TITLE AS "pdbTitle", COUNT(WC.ID) AS "Regions"
FROM PDB_Chains AS PCS
LEFT JOIN WHOLE_FEATURES_PDB_CHAINS AS WC ON WC.PDB_CHAIN_ID = PCS.idPDB_chains, PDB_protein_alignment PPA, PDB_INFOS PIN
WHERE PCS.idPDB_chains = PPA.idPDB_Chains
AND PCS.PDB_id = PIN.PDB_ID
AND PPA.idProteins = (SELECT idProteins from Proteins WHERE ENSEMBL_protein_id = "'+submittedID+'")
GROUP BY PCS.PDB_id, PCS.Chain ORDER BY PCS.PDB_id;
Here's the working solutin based on your kind answers
SELECT PIN.TITLE AS "pdbTitle", COUNT(CASE WHEN WC.STRUCTURAL_FEATURES_ID = 1 then 1 end) AS "PPInterface" , COUNT(CASE WHEN WC.STRUCTURAL_FEATURES_ID = 4 then 1 end) AS "flexibleRegions"
FROM PDB_Chains AS PCS LEFT JOIN WHOLE_FEATURES_PDB_CHAINS AS WC ON WC.PDB_CHAIN_ID = PCS.idPDB_chains, PDB_protein_alignment PPA, PDB_INFOS PIN
WHERE PCS.idPDB_chains = PPA.idPDB_Chains
AND PCS.PDB_id = PIN.PDB_ID
AND PPA.idProteins = (SELECT idProteins from Proteins WHERE ENSEMBL_protein_id = "ENSP00000256078.4")
GROUP BY PCS.PDB_id, PCS.Chain ORDER BY PCS.PDB_id;
You can use case when statement inside your aggregate function.
Try this .
count(case when WC.type = 1 then 1 end) as region_1, similarly repeat for another column.
Select
...
...
sum(if WC.ID = 1 then 1 else 0) as Region1,
sum(if WC.ID = 2 then 1 else 0) as Region2,
sum(if WC.ID = 3 then 1 else 0) as Region3,
sum(if WC.ID = 4 then 1 else 0) as Region4
Might do what you want.
You can use GROUP BY with COUNT to get the required result, e.g.:
SELECT WC.Type, COUNT(WC.ID) AS "Regions"
FROM WHOLE_FEATURES_PDB_CHAINS AS WC
GROUP BY WC.Type;
Update
If you want the counts as pivoted column for each region then you can write inner SELECT queries, e.g.:
SELECT
(SELECT COUNT(ID) FROM WHOLE_FEATURES_PDB_CHAINS WHERE type = 1) AS "Region_1",
(SELECT COUNT(ID) FROM WHOLE_FEATURES_PDB_CHAINS WHERE type = 2) AS "Region_2",
other_column
FROM WHOLE_FEATURES_PDB_CHAINS AS WC
WHERE <some condition>;

MySQL How to make a SELECT SUM from Table and multiplication from other SEARCH?

I have this query
SELECT ps_ur AS UR, COUNT(ps_ur) AS Value
FROM patient_services
GROUP BY UR
UNION ALL
SELECT eng_ur AS UR, COUNT(eng_ur) AS Value
FROM engagements
WHERE LENGTH( eng_ur )>0
GROUP BY UR
Result:
UR Value
002035 3
002400 2
005441 4
...
Now I need to calculate from Patient table Male/Female and multiply by the Value
Like this but right
SELECT
SUM( CASE WHEN patient_gender = 'Male' THEN 1 ELSE 0 END ) Male,
SUM( CASE WHEN patient_gender = 'Female' THEN 1 ELSE 0 END ) Female
FROM patients WHERE patient_ur
How to do this?
In that case you want wrap the first as inner query. Something like below. Now you can access the Value field saying xxx.Value and multiply or do whatever processing needed. Not sure where you want to multiply and thus couldn't reflect it in suggested query. Probably that's left as homework for you.
SELECT
SUM( CASE WHEN patient_gender = 'Male' THEN 1 ELSE 0 END ) Male,
SUM( CASE WHEN patient_gender = 'Female' THEN 1 ELSE 0 END ) Female
FROM patients JOIN (
SELECT ps_ur AS UR, COUNT(ps_ur) AS `Value`
FROM patient_services
GROUP BY UR
UNION ALL
SELECT eng_ur AS UR, COUNT(eng_ur) AS `Value`
FROM engagements
WHERE LENGTH( eng_ur )>0
GROUP BY UR ) xxx ON patients.patient_ur = xxx.UR

How do I calculate the difference of two alias for sorting

Considering the following code:
SELECT SUM(w.valor),
SUM(CASE WHEN w.tipo = '+' THEN w.valor ELSE 0 END) AS total_credit,
SUM(CASE WHEN w.tipo = '-' THEN w.valor ELSE 0 END) AS total_debit,
w.clientUNIQUE,
c.client as cclient
FROM wallet AS w
LEFT JOIN clients AS c ON w.clientUNIQUE = c.clientUNIQUE
WHERE w.status='V'
GROUP BY w.clientUNIQUE
ORDER BY total_credit-total_debit
I'm trying to calculate the difference of two aliased calculated values for sorting purposes, but I'm getting the following error:
Reference 'total_credit' not supported (reference to group function)
What am I doing wrong and how can I order results by using the difference value between the two aliases?
You can't refer to columns by their alias in the same select expression, so there are 2 options...
Repeat the expressions in the order by (yuk):
ORDER BY
SUM(CASE WHEN w.tipo = '+' THEN w.valor ELSE 0 END) AS total_credit -
SUM(CASE WHEN w.tipo = '-' THEN w.valor ELSE 0 END) AS total_debit
Or easier on the brain and easier to maintain (DRY), order via a sub query:
select * from (
<your query without the ORDER BY>
) q
ORDER BY total_credit - total_debit

How to select an "AS field" in MySql?

I have a Query which is separated in different parts. (distance, score and rank)
SELECT Entry.*, Address.*,
(6367.41 * SQRT(2 * (1-cos(RADIANS(Entry.latitude)) * cos(0.92640848333131) * (sin(RADIANS(Entry.longitude)) * sin(0.15361853481704) + cos(RADIANS(Entry.longitude)) * cos(0.15361853481704)) - sin(RADIANS(Entry.latitude)) * sin(0.92640848333131))))
AS distance,
(CASE WHEN `Entry`.`title` LIKE '%%' THEN 50 ELSE 0 END +
CASE WHEN `Entry`.`description` LIKE '%%' THEN 30 ELSE 0 END +
CASE WHEN `Entry`.`description_long` LIKE '%%' THEN 10 ELSE 0 END +
CASE WHEN `Entry`.`product_type` = 1 THEN 0 ELSE 0 END +
CASE WHEN `Entry`.`product_type` = 2 THEN 40 ELSE 0 END +
CASE WHEN `Entry`.`product_type` = 3 THEN 50 ELSE 0 END )
AS score,
(CASE WHEN (score > 100 AND distance <= 10) THEN 1 ELSE 0 END)
rank
FROM `usr_web12_1`.`entries` AS `Entry`
inner JOIN `usr_web12_1`.`entrieslocations` AS `Entrieslocation` ON (`Entry`.`id` = `Entrieslocation`.`entry_id`)
inner JOIN `usr_web12_1`.`addresses` AS `Address` ON (`Address`.`id` = `Entry`.`address_id`)
WHERE ((`Entry`.`title` LIKE '%%') OR (`Entry`.`description` LIKE '%%') OR (`Entry`.`description_long` LIKE '%%') OR (`Entry`.`meta_keywords` LIKE '%%') OR (`Entry`.`filter_keywords` LIKE '%%')) AND `Entry`.`status` = 1 AND
`Entry`.`latitude` Between 52.179974594081 AND 53.978617805919 AND `Entry`.`longitude` Between 7.3045938084915 AND 10.298793591508 AND `Entrieslocation`.`category_id` = 1
GROUP BY `Entry`.`id`
ORDER BY `Entry`.`product_type` desc
LIMIT 10
Question: The rank-part doesn't work "Column not found: 1054 Unknown column 'score' in 'field list'", how can I access a dynamic AS-Field???
Same problem with distance...
Thanks a lot!
You can't use an aliased column name in the select or where clause.
You could use it later in the group by, order by, having clause. See the MySQL doc for that.