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

Row to column transformation in MySQL version 8.0.17 using Pivot

不幸的是 MySQL 没有 PIVOT function 这基本上是我想要做的事情。

我需要 return 使用下面的存储过程将行值设置为列名 link

我使用 csv 格式的外部文件填充数据库 MySql version 8.0.17 的 table。

这是 table 填充了来自外部 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)

现在我需要这个 return 我的意思是将行值设置为列名

+-----------------------+-----------------------+
| Q400                  | Q410                  |
+-----------------------+-----------------------+
| Set n.1               | Set n.1               |
| - Par 1.1             | - Par 1.1             |
| <b>bold text</b>      | <b>bold text</b>      |
| - Par 1.2             | - Par 1.2             |
| normal text           | normal text           |
| Set n.2               | Set n.2               |
| - Par 2.1             | - Par 2.1             |
| <i>italic text</i>    | <i>italic text</i>    |
| - Par 2.2             | - Par 2.2             | 
| <u>underline text</u> | <u>underline text</u> |
| - Par 2.3             | - Par 2.3             | 
| Set n.1               | Set n.1               |
| - Par 1.1             | - Par 1.1             |
| <b>bold text</b>      | <b>bold text</b>      |
| - Par 1.2             | - Par 1.2             |
| normal text           | normal text           |
| Set n.2               | Set n.2               |
| - Par 2.1             | - Par 2.1             |
| <i>italic text</i>    | <i>italic text</i>    | 
| - Par 2.2             | - Par 2.2             | 
| <u>underline text</u> | <u>underline text</u> |
| - Par 2.3             | - Par 2.3             |
+-----------------------+-----------------------+

存储过程和return(很抱歉,如果我添加了SP代码,这个问题就不会发布...

+-----+-------------+-------------+--------+
| sID | sUnity_Q400 | sUnity_Q410 | sUnity |
+-----+-------------+-------------+--------+
|   6 | Q400        | NULL        | Q400   |
|  73 | NULL        | Q410        | Q410   |
|   9 | Q400        | NULL        | Q400   |
|  75 | NULL        | Q410        | Q410   |
|  14 | Q400        | NULL        | Q400   |
|  78 | NULL        | Q410        | Q410   |
|  16 | Q400        | NULL        | Q400   |
|  80 | NULL        | Q410        | Q410   |
|  71 | Q400        | NULL        | Q400   |
|  82 | NULL        | Q410        | Q410   |
|   7 | Q400        | NULL        | Q400   |
|  74 | NULL        | Q410        | Q410   |
|  15 | Q400        | NULL        | Q400   |
|  79 | NULL        | Q410        | Q410   |
|  17 | Q400        | NULL        | Q400   |
|  81 | NULL        | Q410        | Q410   |
|  10 | Q400        | NULL        | Q400   |
|  76 | NULL        | Q410        | Q410   |
|   4 | Q400        | NULL        | Q400   |
|  72 | NULL        | Q410        | Q410   |
|  12 | Q400        | NULL        | Q400   |
|  77 | NULL        | Q410        | Q410   |
+-----+-------------+-------------+--------+
22 rows in set (0.05 sec)

下面table的结构和数据

-- ----------------------------
-- 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);

如果您将 [sID] 替换为行号,您应该能够进行数据透视,该行号将 link [sUnity] 值按其 ID

的顺序排列
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

如果 row_number 不可用,您可以使用它来模仿 row_number

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;