使用 pivot 连接表使用 Mysql 8 版本
Using pivot to join tables using Mysql 8 version
我已经将这两个 table t1
和 t2
存储在一个数据库 MySql 版本 8.0.17
重要的是 table t2
可以包含数千行不同的单元代码(字段 sUn
)...
相反,table t1
仅包含每个单元的方法和代码(字段 TABLE_NAME
)
-- ----------------------------
-- Table structure for t1
-- ----------------------------
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`TABLE_NAME` varchar(255) DEFAULT NULL,
`tDDMMYYHHMMSS` datetime DEFAULT NULL,
`sID` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sID`) USING BTREE,
UNIQUE INDEX `TABLE_NAME`(`TABLE_NAME`) USING BTREE
) ENGINE = InnoDB;
-- ----------------------------
-- Records of t1
-- ----------------------------
INSERT INTO `t1` VALUES ('100', '2021-04-09 12:44:30', 1);
INSERT INTO `t1` VALUES ('11c', '2021-04-09 12:44:30', 2);
INSERT INTO `t1` VALUES ('11f', '2021-04-09 12:44:30', 3);
INSERT INTO `t1` VALUES ('12a', '2021-04-09 12:44:30', 4);
INSERT INTO `t1` VALUES ('12h', '2021-04-09 12:44:30', 5);
-- ----------------------------
-- Table structure for t2
-- ----------------------------
DROP TABLE IF EXISTS `t2`;
CREATE TABLE `t2` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`sUn` varchar(255) DEFAULT NULL,
`sUnName` varchar(255) DEFAULT NULL,
`sContents` longtext NULL,
PRIMARY KEY (`sid`) USING BTREE
) ENGINE = InnoDB;
-- ----------------------------
-- Records of t2
-- ----------------------------
INSERT INTO `t2` VALUES (1, '100', 'NOR', 'Ipsa sua melior fama.');
INSERT INTO `t2` VALUES (2, '100', 'NOR', 'In toto.');
INSERT INTO `t2` VALUES (3, '100', 'NOR', 'Homines, nihil agendo.');
INSERT INTO `t2` VALUES (4, '11C', 'SAR', 'Habere non haberi.');
INSERT INTO `t2` VALUES (5, '11C', 'SAR', 'Vivere est cogitare.');
INSERT INTO `t2` VALUES (6, '11C', 'SAR', 'Urbi et Orbi.');
INSERT INTO `t2` VALUES (7, '11F', 'SAD', 'Inter sidera versor.');
INSERT INTO `t2` VALUES (8, '11F', 'SAD', 'Una tantum.');
INSERT INTO `t2` VALUES (9, '11F', 'SAD', 'Carthago delenda est.');
INSERT INTO `t2` VALUES (10, '12A', 'RIV', 'Status quo.');
INSERT INTO `t2` VALUES (11, '12A', 'RIV', 'Aut aut.');
INSERT INTO `t2` VALUES (12, '12A', 'RIV', 'Condicio sine qua non.\r\n');
INSERT INTO `t2` VALUES (13, '12H', 'CUN', 'Ubi maior minor cessat.');
INSERT INTO `t2` VALUES (14, '12H', 'CUN', 'Carpe diem.');
INSERT INTO `t2` VALUES (15, '12H', 'CUN', 'Venni, vidi, vinsi.');
我试过-没有成功- 一个查询枢轴连接这两个tables return
+------------------------+----------------------+-----------------------+------------------------+-------------------------+
| NOR | SAR | SAD | RIV | CUN |
+------------------------+----------------------+-----------------------+------------------------+-------------------------+
| Ipsa sua melior fama. | Habere non haberi. | Inter sidera versor. | Status quo. | Ubi maior minor cessat. |
| In toto. | Vivere est cogitare. | Una tantum. | Aut aut. | Carpe diem. |
| Homines, nihil agendo. | Urbi et Orbi. | Carthago delenda est. | Condicio sine qua non. | Venni, vidi, vinsi. |
+------------------------+----------------------+-----------------------+------------------------+-------------------------+
我的以下查询有误
任何帮助将不胜感激...谢谢。
SELECT
max(
IF
( t.sUn = q.TABLE_NAME, t.sContents, NULL )) q.sUnName
FROM
( SELECT row_number() over ( PARTITION BY sUn ORDER BY sID ) AS rn, tcs.sUn, tcs.sContents FROM t2 AS tcs ) AS t
JOIN t1 q ON t.sUn = q.TABLE_NAME
GROUP BY
rn
ORDER BY
rn
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.sUnName
FROM
( SELECT row_number() over ( PARTITION BY sUn ORDER BY sID ) AS' at line 4
> Time: 0,001s
更新
新版本使用存储过程...
CREATE DEFINER=`root`@`localhost` PROCEDURE `pivot_20210409`()
BEGIN
SET SESSION group_concat_max_len = 1000000;
SELECT
CONCAT('SELECT ',
GROUP_CONCAT(
CONCAT (
"IF(`sUnName` = '",sUnName,'\',sContents,NULL) AS `',sUnName,'`'
)
),
' FROM `t2`'
) INTO @SQL
FROM
( SELECT row_number() over ( PARTITION BY sUn ORDER BY sID ) AS rn, tcs.sUnName, tcs.sContents FROM t2 AS tcs
GROUP BY tcs.sUnName
) AS data;
SELECT @SQL;
PREPARE stmt FROM @SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
return
+------------------------+----------------------+-----------------------+--------------------------+-------------------------+
| NOR | SAR | SAD | RIV | CUN |
+------------------------+----------------------+-----------------------+--------------------------+-------------------------+
| Ipsa sua melior fama. | NULL | NULL | NULL | NULL |
| In toto. | NULL | NULL | NULL | NULL |
| Homines, nihil agendo. | NULL | NULL | NULL | NULL |
| NULL | Habere non haberi. | NULL | NULL | NULL |
| NULL | Vivere est cogitare. | NULL | NULL | NULL |
| NULL | Urbi et Orbi. | NULL | NULL | NULL |
| NULL | NULL | Inter sidera versor. | NULL | NULL |
| NULL | NULL | Una tantum. | NULL | NULL |
| NULL | NULL | Carthago delenda est. | NULL | NULL |
| NULL | NULL | NULL | Status quo. | NULL |
| NULL | NULL | NULL | Aut aut. | NULL |
| NULL | NULL | NULL | Condicio sine qua non. | NULL |
| NULL | NULL | NULL | NULL | Ubi maior minor cessat. |
| NULL | NULL | NULL | NULL | Carpe diem. |
| NULL | NULL | NULL | NULL | Venni, vidi, vinsi. |
+------------------------+----------------------+-----------------------+--------------------------+-------------------------+
在 MySQL 中,遗憾的是,对于一堆任意命名的列,旋转很难做到。
这会得到你想要的结果(dbfiddle on db-fiddle.com,它提供 MySQL 8.)
WITH pivot AS (
SELECT CASE WHEN SunName = 'NOR' THEN sContents ELSE NULL END NOR,
CASE WHEN SunName = 'SAR' THEN sContents ELSE NULL END SAR,
CASE WHEN SunName = 'SAD' THEN sContents ELSE NULL END SAD,
CASE WHEN SunName = 'RIV' THEN sContents ELSE NULL END RIV,
CASE WHEN SunName = 'CUN' THEN sContents ELSE NULL END CUN,
sId
FROM t2
),
rownums AS (
SELECT sId, row_number() OVER ( PARTITION BY sUn ORDER BY sID ) rn FROM t2
)
SELECT MAX(NOR) NOR, MAX(SAR) SAR, MAX(SAD) SAD, MAX(RIV) RIV, MAX(CUN) CUN
FROM rownums
JOIN pivot ON rownums.sId = pivot.sId
GROUP BY rownums.rn
这个讨厌的子查询执行旋转操作。 (fiddle) 看看它是如何枚举列的?这就是您必须要做的事情
SELECT CASE WHEN SunName = 'NOR' THEN sContents ELSE NULL END NOR,
CASE WHEN SunName = 'SAR' THEN sContents ELSE NULL END SAR,
CASE WHEN SunName = 'SAD' THEN sContents ELSE NULL END SAD,
CASE WHEN SunName = 'RIV' THEN sContents ELSE NULL END RIV,
CASE WHEN SunName = 'CUN' THEN sContents ELSE NULL END CUN,
sId
FROM t2
您可以编写一个使用字符串处理和MySQL's PREPARE statement to synthesize that sort of query. That's a reasonably big job. Advice here的存储过程。
我已经将这两个 table t1
和 t2
存储在一个数据库 MySql 版本 8.0.17
重要的是 table t2
可以包含数千行不同的单元代码(字段 sUn
)...
相反,table t1
仅包含每个单元的方法和代码(字段 TABLE_NAME
)
-- ----------------------------
-- Table structure for t1
-- ----------------------------
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`TABLE_NAME` varchar(255) DEFAULT NULL,
`tDDMMYYHHMMSS` datetime DEFAULT NULL,
`sID` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sID`) USING BTREE,
UNIQUE INDEX `TABLE_NAME`(`TABLE_NAME`) USING BTREE
) ENGINE = InnoDB;
-- ----------------------------
-- Records of t1
-- ----------------------------
INSERT INTO `t1` VALUES ('100', '2021-04-09 12:44:30', 1);
INSERT INTO `t1` VALUES ('11c', '2021-04-09 12:44:30', 2);
INSERT INTO `t1` VALUES ('11f', '2021-04-09 12:44:30', 3);
INSERT INTO `t1` VALUES ('12a', '2021-04-09 12:44:30', 4);
INSERT INTO `t1` VALUES ('12h', '2021-04-09 12:44:30', 5);
-- ----------------------------
-- Table structure for t2
-- ----------------------------
DROP TABLE IF EXISTS `t2`;
CREATE TABLE `t2` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`sUn` varchar(255) DEFAULT NULL,
`sUnName` varchar(255) DEFAULT NULL,
`sContents` longtext NULL,
PRIMARY KEY (`sid`) USING BTREE
) ENGINE = InnoDB;
-- ----------------------------
-- Records of t2
-- ----------------------------
INSERT INTO `t2` VALUES (1, '100', 'NOR', 'Ipsa sua melior fama.');
INSERT INTO `t2` VALUES (2, '100', 'NOR', 'In toto.');
INSERT INTO `t2` VALUES (3, '100', 'NOR', 'Homines, nihil agendo.');
INSERT INTO `t2` VALUES (4, '11C', 'SAR', 'Habere non haberi.');
INSERT INTO `t2` VALUES (5, '11C', 'SAR', 'Vivere est cogitare.');
INSERT INTO `t2` VALUES (6, '11C', 'SAR', 'Urbi et Orbi.');
INSERT INTO `t2` VALUES (7, '11F', 'SAD', 'Inter sidera versor.');
INSERT INTO `t2` VALUES (8, '11F', 'SAD', 'Una tantum.');
INSERT INTO `t2` VALUES (9, '11F', 'SAD', 'Carthago delenda est.');
INSERT INTO `t2` VALUES (10, '12A', 'RIV', 'Status quo.');
INSERT INTO `t2` VALUES (11, '12A', 'RIV', 'Aut aut.');
INSERT INTO `t2` VALUES (12, '12A', 'RIV', 'Condicio sine qua non.\r\n');
INSERT INTO `t2` VALUES (13, '12H', 'CUN', 'Ubi maior minor cessat.');
INSERT INTO `t2` VALUES (14, '12H', 'CUN', 'Carpe diem.');
INSERT INTO `t2` VALUES (15, '12H', 'CUN', 'Venni, vidi, vinsi.');
我试过-没有成功- 一个查询枢轴连接这两个tables return
+------------------------+----------------------+-----------------------+------------------------+-------------------------+
| NOR | SAR | SAD | RIV | CUN |
+------------------------+----------------------+-----------------------+------------------------+-------------------------+
| Ipsa sua melior fama. | Habere non haberi. | Inter sidera versor. | Status quo. | Ubi maior minor cessat. |
| In toto. | Vivere est cogitare. | Una tantum. | Aut aut. | Carpe diem. |
| Homines, nihil agendo. | Urbi et Orbi. | Carthago delenda est. | Condicio sine qua non. | Venni, vidi, vinsi. |
+------------------------+----------------------+-----------------------+------------------------+-------------------------+
我的以下查询有误
任何帮助将不胜感激...谢谢。
SELECT
max(
IF
( t.sUn = q.TABLE_NAME, t.sContents, NULL )) q.sUnName
FROM
( SELECT row_number() over ( PARTITION BY sUn ORDER BY sID ) AS rn, tcs.sUn, tcs.sContents FROM t2 AS tcs ) AS t
JOIN t1 q ON t.sUn = q.TABLE_NAME
GROUP BY
rn
ORDER BY
rn
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.sUnName FROM ( SELECT row_number() over ( PARTITION BY sUn ORDER BY sID ) AS' at line 4 > Time: 0,001s
更新
新版本使用存储过程...
CREATE DEFINER=`root`@`localhost` PROCEDURE `pivot_20210409`()
BEGIN
SET SESSION group_concat_max_len = 1000000;
SELECT
CONCAT('SELECT ',
GROUP_CONCAT(
CONCAT (
"IF(`sUnName` = '",sUnName,'\',sContents,NULL) AS `',sUnName,'`'
)
),
' FROM `t2`'
) INTO @SQL
FROM
( SELECT row_number() over ( PARTITION BY sUn ORDER BY sID ) AS rn, tcs.sUnName, tcs.sContents FROM t2 AS tcs
GROUP BY tcs.sUnName
) AS data;
SELECT @SQL;
PREPARE stmt FROM @SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
return
+------------------------+----------------------+-----------------------+--------------------------+-------------------------+
| NOR | SAR | SAD | RIV | CUN |
+------------------------+----------------------+-----------------------+--------------------------+-------------------------+
| Ipsa sua melior fama. | NULL | NULL | NULL | NULL |
| In toto. | NULL | NULL | NULL | NULL |
| Homines, nihil agendo. | NULL | NULL | NULL | NULL |
| NULL | Habere non haberi. | NULL | NULL | NULL |
| NULL | Vivere est cogitare. | NULL | NULL | NULL |
| NULL | Urbi et Orbi. | NULL | NULL | NULL |
| NULL | NULL | Inter sidera versor. | NULL | NULL |
| NULL | NULL | Una tantum. | NULL | NULL |
| NULL | NULL | Carthago delenda est. | NULL | NULL |
| NULL | NULL | NULL | Status quo. | NULL |
| NULL | NULL | NULL | Aut aut. | NULL |
| NULL | NULL | NULL | Condicio sine qua non. | NULL |
| NULL | NULL | NULL | NULL | Ubi maior minor cessat. |
| NULL | NULL | NULL | NULL | Carpe diem. |
| NULL | NULL | NULL | NULL | Venni, vidi, vinsi. |
+------------------------+----------------------+-----------------------+--------------------------+-------------------------+
在 MySQL 中,遗憾的是,对于一堆任意命名的列,旋转很难做到。
这会得到你想要的结果(dbfiddle on db-fiddle.com,它提供 MySQL 8.)
WITH pivot AS (
SELECT CASE WHEN SunName = 'NOR' THEN sContents ELSE NULL END NOR,
CASE WHEN SunName = 'SAR' THEN sContents ELSE NULL END SAR,
CASE WHEN SunName = 'SAD' THEN sContents ELSE NULL END SAD,
CASE WHEN SunName = 'RIV' THEN sContents ELSE NULL END RIV,
CASE WHEN SunName = 'CUN' THEN sContents ELSE NULL END CUN,
sId
FROM t2
),
rownums AS (
SELECT sId, row_number() OVER ( PARTITION BY sUn ORDER BY sID ) rn FROM t2
)
SELECT MAX(NOR) NOR, MAX(SAR) SAR, MAX(SAD) SAD, MAX(RIV) RIV, MAX(CUN) CUN
FROM rownums
JOIN pivot ON rownums.sId = pivot.sId
GROUP BY rownums.rn
这个讨厌的子查询执行旋转操作。 (fiddle) 看看它是如何枚举列的?这就是您必须要做的事情
SELECT CASE WHEN SunName = 'NOR' THEN sContents ELSE NULL END NOR,
CASE WHEN SunName = 'SAR' THEN sContents ELSE NULL END SAR,
CASE WHEN SunName = 'SAD' THEN sContents ELSE NULL END SAD,
CASE WHEN SunName = 'RIV' THEN sContents ELSE NULL END RIV,
CASE WHEN SunName = 'CUN' THEN sContents ELSE NULL END CUN,
sId
FROM t2
您可以编写一个使用字符串处理和MySQL's PREPARE statement to synthesize that sort of query. That's a reasonably big job. Advice here的存储过程。