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