2017-11-11 2 views
1

두 매개 변수 (kolagg)로 프로 시저를 만들어야합니다. kol이이 열이며, agg은 집계 함수입니다.집계 함수 프로 시저

가정하자 나는 다음과 같은 테이블이 있습니다

+---------+---------+ 
| X (int) | Y (int) | 
+---------+---------+ 
| 5  | 2  | 
| 4  | 4  | 
+---------+---------+ 

내가 절차 ('X','sum')를 호출 할 - 다음은 SELECT SUM(x) FROM table 그래서 9 ('Y','avg')SELECT AVG(y) FROM table을 보여줍니다 그래서 3

내가 뭔가를하지만 아무튼 SUM, AVG, MINMAX의 경우 작동합니다 (SUM, AVG, MINMAX이 0 일 때만 작동합니다. 왜) 모르겠어요

-- I skipped some lines in procedure, only this is necessary 

BEGIN 
    IF(kol IN (select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where 
    TABLE_NAME='table')) THEN 

    -- getting every column for table above 
    SELECT (
     CASE 
     WHEN agg='SUM' THEN sum(kol) 
     WHEN agg='COUNT' THEN count(kol) 
     WHEN agg='AVG' THEN avg(kol) 
     WHEN agg='MAX' THEN max(kol) 
     WHEN agg='MIN' THEN min(kol) 
    END) Result FROM table; 
    END IF; 
END 

답변

1

당신은 같은 솔루션을 사용할 수 있습니다 다음 :

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 
:

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// 

나는 당신의 데이터가이 솔루션을 시도하고 다음과 같은 결과를 얻을 수

집계 함수에서 매개 변수로 column 매개 변수를 사용할 수 없습니다. 그러나 문자열을 작성하여 준비된 명령문에 사용할 수 있습니다 (위의 솔루션 참조).

사용자 변수는 데이터 값을 제공하기위한 것입니다. 테이블이나 데이터베이스 이름이 예상되는 컨텍스트에서 또는 SELECT와 같은 예약어와 같이 식별자로 또는 식별자의 일부로 SQL 문에서 직접 사용할 수 없습니다.

사용자 변수를 사용하여 식별자를 제공 할 수 없다는이 원칙의 예외는 나중에 실행할 준비된 명령문으로 사용할 문자열을 구성 할 때입니다. 이 경우 사용자 변수를 사용하여 명령문의 일부를 제공 할 수 있습니다.

소스 : 당신이 코멘트에 몇 가지 추가 정보를 제공하면https://dev.mysql.com/doc/refman/5.7/en/user-variables.html


나는 다음과 같은 솔루션에 PROCEDURE을 변경했습니다.

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 
+0

네, 감사합니다,하지만 난했습니다해야하는지 덧붙여서 select에 입력 매개 변수를 표시하고 concat에 col 및 agg를 추가하면 작동하지 않습니다. 출력은 다음과 같아야합니다 - x | 합계 | 9 – jakub1998

+0

@ jakub1998 - 예상 결과와 함께 업데이트 된 답변을 참조하십시오. –

+0

정말 고마워요! – jakub1998