Sql 聚合函数过程
我必须用两个参数做一个过程:Sql 聚合函数过程,sql,mariadb,Sql,Mariadb,我必须用两个参数做一个过程:kol和aggkol显然是列,agg是聚合函数 假设我有下表: +---------+---------+ | X (int) | Y (int) | +---------+---------+ | 5 | 2 | | 4 | 4 | +---------+---------+ 我想调用过程('X','sum')-然后它显示从表中选择sum(X)so9('Y','avg')显示从表中选择平均值(Y)so 3 我有一些东
kol
和agg
kol
显然是列,agg
是聚合函数
假设我有下表:
+---------+---------+
| X (int) | Y (int) |
+---------+---------+
| 5 | 2 |
| 4 | 4 |
+---------+---------+
我想调用过程('X','sum')
-然后它显示从表中选择sum(X)
so9<代码>('Y','avg')显示从表中选择平均值(Y)
so 3
我有一些东西,但当涉及到SUM
,AVG
,MIN
和MAX
时它不起作用,它只在计数时起作用(对于SUM
,AVG
,MIN
和MAX
显示0,不知道为什么):
您可以使用如下解决方案:
DELIMITER //
CREATE PROCEDURE testProc (IN col VARCHAR(10), IN agg VARCHAR(10))
BEGIN
SET @select = '';
-- get the select part with the aggregation function.
-- using UPPER to allow case-insensitive input.
SELECT CASE
WHEN UPPER(agg) = 'SUM' THEN CONCAT('SUM(', col, ')')
WHEN UPPER(agg) = 'COUNT' THEN CONCAT('COUNT(', col, ')')
WHEN UPPER(agg) = 'AVG' THEN CONCAT('AVG(', col, ')')
WHEN UPPER(agg) = 'MAX' THEN CONCAT('MAX(', col, ')')
WHEN UPPER(agg) = 'MIN' THEN CONCAT('MIN(', col, ')')
END
INTO @select;
-- create and prepare the full statement.
SET @stmt = CONCAT('SELECT ', @select, ' AS Result FROM table_name');
PREPARE stmtExec FROM @stmt;
-- execute the statement.
EXECUTE stmtExec;
END//
我用您的数据尝试了此解决方案,并得到以下结果:
CALL testProc('x', 'SUM'); -- 9
CALL testProc('y', 'SUM'); -- 6
CALL testProc('x', 'COUNT'); -- 2
CALL testProc('y', 'COUNT'); -- 2
CALL testProc('x', 'AVG'); -- 4.500
CALL testProc('y', 'AVG'); -- 3.000
CALL testProc('x', 'MAX'); -- 5
CALL testProc('y', 'MAX'); -- 4
CALL testProc('x', 'MIN'); -- 4
CALL testProc('y', 'MIN'); -- 2
不能将列参数用作聚合函数的参数。但您可以创建一个字符串,并在准备好的语句中使用它(请参见上面的解决方案):
用户变量旨在提供数据值。它们不能直接在SQL语句中用作标识符或标识符的一部分,例如在需要表名或数据库名的上下文中,或用作保留字(如SELECT)
用户变量不能用于提供标识符这一原则的一个例外是,当您构造一个字符串用作准备好的语句以供以后执行时。在这种情况下,用户变量可用于提供语句的任何部分
来源:
在您在评论中提供了一些附加信息之后,我将更改为以下解决方案。在这里,您还可以获得结果的列名和聚合函数:
DELIMITER //
CREATE PROCEDURE testProc (IN col VARCHAR(10), IN agg VARCHAR(10))
BEGIN
SET @select = '';
-- get the select part with the aggregation function.
-- using UPPER to allow case-insensitive input.
SELECT CASE
WHEN UPPER(agg) = 'SUM' THEN CONCAT('SUM(', col, ')')
WHEN UPPER(agg) = 'COUNT' THEN CONCAT('COUNT(', col, ')')
WHEN UPPER(agg) = 'AVG' THEN CONCAT('AVG(', col, ')')
WHEN UPPER(agg) = 'MAX' THEN CONCAT('MAX(', col, ')')
WHEN UPPER(agg) = 'MIN' THEN CONCAT('MIN(', col, ')')
END
INTO @select;
-- create and prepare the full statement.
SET @stmt = CONCAT('SELECT CONCAT(\'', col, '|', UPPER(agg), '|\', ', @select, ') AS Result FROM table_name');
PREPARE stmtExec FROM @stmt;
-- execute the statement.
EXECUTE stmtExec;
END//
因此,我再次测试了此解决方案,现在得到以下结果:
CALL testProc('x', 'SUM'); -- x|SUM|9
CALL testProc('y', 'SUM'); -- y|SUM|6
CALL testProc('x', 'COUNT'); -- x|COUNT|2
CALL testProc('y', 'COUNT'); -- y|COUNT|2
CALL testProc('x', 'AVG'); -- x|AVG|4.5000
CALL testProc('y', 'AVG'); -- y|AVG|3.0000
CALL testProc('x', 'MAX'); -- x|MAX|5
CALL testProc('y', 'MAX'); -- y|MAX|4
CALL testProc('x', 'MIN'); -- x|MIN|4
CALL testProc('y', 'MIN'); -- y|MIN|2
好的,谢谢,但我应该添加的是,我还想在select中显示输入参数,如果我将col和agg添加到concat,它们不起作用,输出应该是这样的-x | sum |9@jakub1998-查看更新的答案和预期结果。
CALL testProc('x', 'SUM'); -- x|SUM|9
CALL testProc('y', 'SUM'); -- y|SUM|6
CALL testProc('x', 'COUNT'); -- x|COUNT|2
CALL testProc('y', 'COUNT'); -- y|COUNT|2
CALL testProc('x', 'AVG'); -- x|AVG|4.5000
CALL testProc('y', 'AVG'); -- y|AVG|3.0000
CALL testProc('x', 'MAX'); -- x|MAX|5
CALL testProc('y', 'MAX'); -- y|MAX|4
CALL testProc('x', 'MIN'); -- x|MIN|4
CALL testProc('y', 'MIN'); -- y|MIN|2