Reputation: 497
I've these two tables t1
and t2
stored an a database MySql version 8.0.17
It's important to say that the table t2
can contain thousands of rows with different unit code (field sUn
)...
Instead the table t1
contains only the how and code of each unit (field 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.');
I've tried -without success- one query pivot join these two tables for this 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. |
+------------------------+----------------------+-----------------------+------------------------+-------------------------+
My query below with error
Any help would greatly appreciate... Thank you.
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
UPDATE
New version using stored procedure...
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. |
+------------------------+----------------------+-----------------------+--------------------------+-------------------------+
Upvotes: 0
Views: 1378
Reputation: 108806
In MySQL, sad to say, pivoting is hard to do for a mess of arbitrarily named columns.
This gets the result you want (dbfiddle on db-fiddle.com, which offers 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
This nasty subquery does the pivoting operation. (fiddle) See how it enumerates the columns? That's pretty much what you have to do
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
You can write a stored procedure that uses string processing and MySQL's PREPARE statement to synthesize that sort of query. That's a reasonably big job. Advice here.
Upvotes: 1