I am trying to calculate a percentage as a derived column in my query.
My query is returning all the expected data but NULL on the percentage column.
SELECT items_type_catalog.id,
items_type_catalog.description,
items_header.tipo, items_type_catalog.color,
@solved :=COUNT(CASE WHEN (items_header.stato = 4 OR items_header.stato= 5) THEN 1 END) AS solved,
@tutti:=count(items_header.id) as tutti,
(ROUND(@solved/@tutti,0)*100) as percentage
FROM items_type_catalog LEFT JOIN items_header ON items_type_catalog.id=items_header.tipo AND items_header.progetto=1
GROUP BY items_type_catalog.id, tipo
I cannot see what I am doing wrong on this point. Why is it not doing the math and returns NULL?
>Solution :
https://dev.mysql.com/doc/refman/8.0/en/user-variables.html
The order of evaluation for expressions involving user variables is undefined. For example, there is no guarantee that
SELECT @a, @a:=@a+1evaluates@afirst and then performs the assignment.
This means that the usage you show, where you assume @solved and @tutti are assigned before you calculate the percentage expression, is not reliable.
A better way to do this is to put your query in a subquery, and then calculate the expression in the outer query using the aliases:
SELECT id, description, tipo, color, solved, tutti,
(ROUND(solved/tutti,0)*100) as percentage
FROM (
SELECT
items_type_catalog.id,
items_type_catalog.description,
items_header.tipo,
items_type_catalog.color,
COUNT(CASE WHEN (items_header.stato = 4 OR items_header.stato= 5) THEN 1 END) AS solved,
COUNT(items_header.id) AS tutti
FROM items_type_catalog
LEFT JOIN items_header
ON items_type_catalog.id=items_header.tipo AND items_header.progetto=1
GROUP BY items_type_catalog.id, tipo
) AS t;