Here is the code of the (My)SQL function (it works outside of the function),
but I can’t manage to save it as a function for further reuse…
This is an example of the working query:
SELECT
(
SUM(Items_Available * Store_Sales) - (SUM(Items_Available) * SUM(Store_Sales)) / COUNT(*)
) / (
SQRT(
SUM(Items_Available * Items_Available) - (SUM(Items_Available) * SUM(Items_Available)) / COUNT(*)
) * SQRT(
SUM(Store_Sales * Store_Sales) - (SUM(Store_Sales) * SUM(Store_Sales)) / COUNT(*)
)
) as pearson_r
FROM
store_sales
I’ve extracted the business logic into this UDF:
DELIMITER $$
DROP FUNCTION IF EXISTS PEARSON_R $$
CREATE FUNCTION PEARSON_R(X INT, Y INT) RETURNS FLOAT DETERMINISTIC
BEGIN
RETURN (SUM(X * Y) - (SUM(X) * SUM(Y)) / COUNT(*)) / (SQRT(SUM(X * X) - (SUM(X) * SUM(X)) / COUNT(*)) * SQRT(SUM(Y * Y) - (SUM(Y) * SUM(Y)) / COUNT(*)));
END$$
DELIMITER ;
When I try to execute this code in command line, I get this useless error message:
> SELECT PEARSON_R(Items_Available, Store_Sales) FROM store_sales;
ERROR 1111 (HY000): Invalid use of group function
Do you have any idea?
I tried to simplify a lot the function but once I use a group function, I have this error.
2
Answers
While I see nothing wrong with the function implementation per-se, I notice that you are using aggregate function without actually aggregating anything (so you’re not using the GROUP BY clause)
Post with a similar error as you: ERROR 1111 (HY000): Invalid use of group function
The main problem is that your function refers to aggregate functions :
COUNT
,SUM
… These are not valid in the scope of the function, that cannot refer, infer, or even assume anything about the context of the calling query.In my opinion the function code should not even compile (but it does) ; we can reproduce the issue with just:
If you want to move some of the logic to a function, then it would need to take each and every aggregate value as an argument. The signature would look like:
Then you would invoke it like so in the query:
Note that you could very well use a subquery (or a lateral join) rather than a function: