MySQL版本8.0.17中使用Pivot的行到列转换

MySQL版本8.0.17中使用Pivot的行到列转换,mysql,stored-procedures,pivot,pivot-table,Mysql,Stored Procedures,Pivot,Pivot Table,不幸的是,MySQL没有一个PIVOT函数,这基本上就是我想要做的 我需要在返回时使用下面的存储过程将行值设置为列名 我使用csv格式的外部文件填充数据库MySql 8.0.17版的表 这是一个包含外部csv文件数据的表格 +-----------------------+--------+-----+ | contents | sUnity | sID | +-----------------------+--------+-----+ | Set n.1

不幸的是,
MySQL
没有一个
PIVOT函数
,这基本上就是我想要做的

我需要在返回时使用下面的存储过程将行值设置为列名

我使用csv格式的外部文件填充数据库MySql 8.0.17版的表

这是一个包含外部csv文件数据的表格

+-----------------------+--------+-----+
| contents              | sUnity | sID |
+-----------------------+--------+-----+
| Set n.1               | Q400   |   4 |
| - Par 1.1             | Q400   |   6 |
| <b>bold text</b>      | Q400   |   7 |
| - Par 1.2             | Q400   |   9 |
| normal text           | Q400   |  10 |
| Set n.2               | Q400   |  12 |
| - Par 2.1             | Q400   |  14 |
| <i>italic text</i>    | Q400   |  15 |
| - Par 2.2             | Q400   |  16 |
| <u>underline text</u> | Q400   |  17 |
| - Par 2.3             | Q400   |  71 |
| Set n.1               | Q410   |  72 |
| - Par 1.1             | Q410   |  73 |
| <b>bold text</b>      | Q410   |  74 |
| - Par 1.2             | Q410   |  75 |
| normal text           | Q410   |  76 |
| Set n.2               | Q410   |  77 |
| - Par 2.1             | Q410   |  78 |
| <i>italic text</i>    | Q410   |  79 |
| - Par 2.2             | Q410   |  80 |
| <u>underline text</u> | Q410   |  81 |
| - Par 2.3             | Q410   |  82 |
+-----------------------+--------+-----+
22 rows in set (0.03 sec)
下表的结构和数据

-- ----------------------------
-- Table structure for t_contents_s3sv_1_2021
-- ----------------------------
DROP TABLE IF EXISTS `t_contents_s3sv_1_2021`;
CREATE TABLE `t_contents_s3sv_1_2021`  (
  `contents` varchar(255) DEFAULT NULL,
  `sUnity` varchar(50) DEFAULT NULL,
  `sID` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`sID`) USING BTREE,
  UNIQUE INDEX `contents`(`contents`, `sUnity`) USING BTREE
) ENGINE = InnoDB;

-- ----------------------------
-- Records of t_contents_s3sv_1_2021
-- ----------------------------
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 1.1', 'Q400', 6);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 1.1', 'Q410', 73);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 1.2', 'Q400', 9);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 1.2', 'Q410', 75);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 2.1', 'Q400', 14);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 2.1', 'Q410', 78);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 2.2', 'Q400', 16);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 2.2', 'Q410', 80);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 2.3', 'Q400', 71);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('- Par 2.3', 'Q410', 82);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('<b>bold text</b>', 'Q400', 7);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('<b>bold text</b>', 'Q410', 74);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('<i>italic text</i>', 'Q400', 15);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('<i>italic text</i>', 'Q410', 79);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('<u>underline text</u>', 'Q400', 17);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('<u>underline text</u>', 'Q410', 81);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('normal text', 'Q400', 10);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('normal text', 'Q410', 76);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('Set n.1', 'Q400', 4);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('Set n.1', 'Q410', 72);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('Set n.2', 'Q400', 12);
INSERT INTO `t_contents_s3sv_1_2021` VALUES ('Set n.2', 'Q410', 77);
——----------------------------
--t_目录的表结构\u s3sv\u 1\u 2021
-- ----------------------------
删除表格(如果存在)`t_contents_s3sv_1_2021`;
创建表't_contents_s3sv_1_2021`(
`contents`varchar(255)默认为空,
`sUnity`varchar(50)默认为空,
`sID`int(11)非空自动增量,
使用BTREE的主键(`sID`),
使用BTREE的唯一索引'contents'('contents','sUnity`)
)引擎=InnoDB;
-- ----------------------------
--t_目录记录\u s3sv\u 1\u 2021
-- ----------------------------
插入“Ti CordssS3VS1 12021”值(‘PAR 1.1’、‘Q400’、6’);
插入“Ti CordssS3VS1 12021”值(‘PAR 1.1’、‘Q410’、73’);
插入“Ti CordssS3VS1 12021”值(‘PAR 1.2’、‘Q400’、9’);
插入“Ti CordssS3VS1 12021”值(‘PAR 1.2’、‘Q410’、75’);
插入“Ti CordssS3VS1 12021”值(‘PAR 2.1’、‘Q400’、14’);
插入“Ti CordssS3VS1 12021”值(‘PAR 2.1’、‘Q410’、78’);
插入“Ti CordssS3VS1 12021”值(‘PAR 2.2’、‘Q400’、16’);
插入“Ti CordssS3VS1 12021”值(‘PAR 2.2’、‘Q410’、80’);
插入“Ti CordssS3VS1 12021”值(‘PAR 2.3’、‘Q400’、71’);
插入“Ti CordssS3VS1 12021”值(‘PAR 2.3’、‘Q410’、82’);
在't_contents_s3sv_1_2021'值中插入('bold text','Q400',7);
在't_contents_s3sv_1_2021'值中插入('bold text','Q410',74);
在't_contents_s3sv_1_2021'值中插入('斜体文本','Q400',15);
在't_contents_s3sv_1_2021'值中插入('斜体文本','Q410',79);
在't_contents_s3sv_1_2021'值中插入('下划线文本','Q400',17);
在't_contents_s3sv_1_2021'值中插入('下划线文本','Q410',81);
在't_contents_s3sv_1_2021'值中插入('normal text','Q400',10);
在't_contents_s3sv_1_2021'值中插入('normal text','Q410',76);
在't_contents_s3sv_1_2021'值中插入('Set n.1','Q400',4);
在't_contents_s3sv_1_2021'值中插入('Set n.1','Q410',72);
在't_contents_s3sv_1_2021'值中插入('Set n.2','Q400',12);
在't_contents_s3sv_1_2021'值中插入('Set n.2','Q410',77);

如果将[sID]替换为按ID顺序链接[sUnity]值的行号,则应该能够透视

select      max(IF(sUnity = 'Q400', t.contents, NULL))    [Q400]
            , max(IF(sUnity = 'Q410', t.contents, NULL))  [Q410]
from        (   select  row_number() over (partition by sUnity order by sID) as rn
                        , tcs.sUnity
                        , tcs.contents
                from    dbo.t_contents_s3sv_1_2021 as tcs) as t
group by    rn
order by    rn
如果行号不可用,您可以使用它来模拟行号

SET @row_number := 0;
SELECT MAX(IF(sUnity = 'Q400', contents, NULL)) Q400,
       MAX(IF(sUnity = 'Q410', contents, NULL)) Q410
FROM(
SELECT 
    @row_number:=CASE
        WHEN @sUnity = sUnity 
          THEN 
              @row_number + 1
          ELSE 
               1
        END AS num,
    @sUnity:=sUnity sUnity,
    contents
FROM
    t_contents_s3sv_1_2021
ORDER BY 
    sUnity, sID
  ) t
GROUP BY num;

由于分组似乎是基于按sUnity和sID排序的行号进行的,所以您没有可按其分组的列。生成此分组排名编号,并根据该编号分组。请参阅此答案以生成分组行数(排名):感谢您的帮助
select      max(IF(sUnity = 'Q400', t.contents, NULL))    [Q400]
            , max(IF(sUnity = 'Q410', t.contents, NULL))  [Q410]
from        (   select  row_number() over (partition by sUnity order by sID) as rn
                        , tcs.sUnity
                        , tcs.contents
                from    dbo.t_contents_s3sv_1_2021 as tcs) as t
group by    rn
order by    rn
SET @row_number := 0;
SELECT MAX(IF(sUnity = 'Q400', contents, NULL)) Q400,
       MAX(IF(sUnity = 'Q410', contents, NULL)) Q410
FROM(
SELECT 
    @row_number:=CASE
        WHEN @sUnity = sUnity 
          THEN 
              @row_number + 1
          ELSE 
               1
        END AS num,
    @sUnity:=sUnity sUnity,
    contents
FROM
    t_contents_s3sv_1_2021
ORDER BY 
    sUnity, sID
  ) t
GROUP BY num;