2012-12-22 1 views
1

나는이 질문이나 그 차이가 여러 번 묻는 것을 알고 있으며 솔루션 구현을 시도해 보았지만 완료하는 데 어려움이 있습니다.동적 피벗 테이블 또는 크로스 탭에 MySQL을 사용하는 방법

나는 아주 간단한 테이블에 Date1, Report_ #, Name의 세 가지 데이터 열이 있습니다. Date와 다양한 이름을 머리글 탭으로 피벗하고 아래에 모든 보고서 번호를 표시하고 싶습니다. 내가 http://www.artfulsoftware.com/infotree/queries.php#78에서 무엇을해야하는지에 대한 아이디어를 얻을 수 있었다

Report | Date | Name      Date | Name1 | Name2 | Name3 
-----------------------     ------------------------------ 
1  | 4-5-12 | Name1     4-5-12 | 1  | 2  | 3 
2  | 4-5-12 | Name2  ----->  4-6-12 | 4  | 5  | 6 
3  | 4-5-12 | Name3     4-7-12 | 7  | 8  | 9 
4  | 4-6-12 | Name1      
5  | 4-6-12 | Name2      
6  | 4-6-12 | Name3      
7  | 4-7-12 | Name1 
8  | 4-7-12 | Name2 
9  | 4-7-12 | Name3 

을하지만 난 붙어 :

그래서 같을 것이다.

열 이름을 수동으로 분리하고 각 이름 아래에 보고서 번호를 나열 할 수 있었지만 고유 한 이름을 동적으로 찾아서 열 이름을 만들고 해당 보고서를 나열하려고합니다.

그래서 고유 한 이름을 찾아 올바른 코드를 출력하는 절차를 만들었습니다. 이제는 프로 시저 결과를 쿼리에 연결하는 데 어려움이 있습니다. 그리고 위의 링크는 아무리해도 도움이되지 않습니다 (이 단계를 건너 뛰는 것 같습니다). 그래서 여기

수동 방법에 대한 코드입니다 :

SELECT `DATE`, 
GROUP_CONCAT(CASE `Name` WHEN 'Name1' THEN `Report` END) AS 'Name1', 
GROUP_CONCAT(CASE `Name` WHEN 'Name2' THEN `Report` END) AS 'Name2' 
FROM `report_db` GROUP BY `DATE` ORDER BY `DATE`; 

그리고 여기에 코드입니다 데이터베이스의 모든 고유 한 이름에 대한 동적 인쇄합니다 GROUP_CONCAT (...을 :

DROP PROCEDURE IF EXISTS writecountpivot; 
DELIMITER | 
CREATE PROCEDURE writecountpivot(db CHAR(64), tbl CHAR(64), col CHAR(64)) 
BEGIN 
DECLARE datadelim CHAR(1) DEFAULT '"'; 
DECLARE singlequote CHAR(1) DEFAULT CHAR(39); 
DECLARE comma CHAR(1) DEFAULT ','; 
SET @sqlmode = (SELECT @@sql_mode); 
SET @@sql_mode=''; 
    SET @sql = CONCAT('SELECT DISTINCT CONCAT(', singlequote, 
        ',group_concat(IF(', col, ' = ', datadelim, singlequote, comma, 
        col, comma, singlequote, datadelim, comma, '`IR NO`,null)) AS `', 
        singlequote, comma, col, comma, singlequote, '`', singlequote, 
        ') AS countpivotarg FROM ', db, '.', tbl, 
        ' WHERE ', col, ' IS NOT NULL'); 
    -- UNCOMMENT TO SEE THE MIDLEVEL CODE: 
    -- SELECT @sql; 
    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
    DROP PREPARE stmt; 
    SET @@[email protected]; 
END 
| 
DELIMITER ; 
CALL writecountpivot('database','`report_db`','name'); 

이고 위의 코드 결과는 다음과 같습니다.

,group_concat(IF(name = "Name1",`IR NO`,null)) AS `Name1` 
,group_concat(IF(name = "Name2",`IR NO`,null)) AS `Name2` 
,group_concat(IF(name = "Name3",`IR NO`,null)) AS `Name3` 

** 어떻게이 텍스트 및 플러그 내 SQL에? 프로 시저와 쿼리를 함께 쓰려면 어떻게해야합니까? **

답변

3

정확히 무엇을 하려는지 알기는 어렵지만, 임의의 피벗을 수행 할 수있는 프로 시저를 만들려고한다면, 더 많은 인수 (예 : 피벗 할 열과 값을 찾을 수있는 열)를 제공해야합니다.

또한 준비된 명령문 내에서 준비된 명령문을 작성해야합니다. 가장 바깥 쪽 문은 지정된 열의 고유 한 값을 기준으로 실행될 수있는 GROUP_CONCAT() 표현을 구축 GROUP_CONCAT()를 사용합니다 :

CREATE FUNCTION SQL_ESC(_identifier VARCHAR(64)) 
RETURNS VARCHAR(130) DETERMINISTIC 
RETURN CONCAT('`',REPLACE(_identifier,'`','``'),'`')// 

CREATE PROCEDURE writecountpivot(
    IN _db_nm VARCHAR(64), 
    IN _tb_nm VARCHAR(64), 
    IN _cl_gp VARCHAR(64), 
    IN _cl_pv VARCHAR(64), 
    IN _cl_vl VARCHAR(64) 
) BEGIN 
    SET @sql := CONCAT(
    "SELECT CONCAT(' 
       SELECT ",SQL_ESC(_cl_gp),",', 
       GROUP_CONCAT(DISTINCT CONCAT(
       'GROUP_CONCAT(IF(", 
        SQL_ESC(_cl_pv),"=',QUOTE(",SQL_ESC(_cl_pv),"),' 
       , ",SQL_ESC(_cl_vl)," 
       , NULL 
       )) AS ',SQL_ESC(",SQL_ESC(_cl_pv),") 
      )), ' 
       FROM  ",SQL_ESC(_db_nm),".",SQL_ESC(_tb_nm)," 
       GROUP BY ",SQL_ESC(_cl_gp)," 
      ') 
    INTO @sql 
    FROM ",SQL_ESC(_db_nm),".",SQL_ESC(_tb_nm) 
); 

    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 

    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 
END// 

sqlfiddle에를 참조하십시오.

+0

음 .... 고마워. 나는 그것을 생각해야한다 : 프로 시저의 결과를 SQL 코드에 연결하거나 두 프로 시저를 결합하여 실행한다. – user139301