1

この質問またはその変形が何度も尋ねられていることを知っており、解決策を実装しようとさえしましたが、それを完了するのに苦労しています。

Date1、Report_#、Name の 3 つのデータ列を持つ非常に単純なテーブルがあります。日付とさまざまな名前をヘッダー タブとしてピボットし、すべてのレポート番号を下に表示したいと思います。

したがって、次のようになります。

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

http://www.artfulsoftware.com/infotree/queries.php#78から何をすべきかのアイデアを得ることができましたが、行き詰まっています。

列名を手動で分離し、各名前の下にレポート # をリストすることができましたが、動的に個別の名前を見つけて列名にし、対応するレポートをリストしたいと考えています。

そこで、個別の名前を見つけて正しいコードを出力するプロシージャを作成しました。手順の結果をクエリに組み込むのに苦労しています。そして、上記のリンクはまったく役に立ちません (そのステップをスキップしているようです)。

したがって、手動の方法のコードは次のとおりです。

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 @@sql_mode=@sqlmode; 
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 に挿入するにはどうすればよいでしょうか? プロシージャとクエリを組み合わせるにはどうすればよいですか?**

4

1 に答える 1

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で参照してください。

于 2012-12-23T00:28:40.293 に答える