使用数据库 MySql 版本 8.0.17 的分层数据
Hierarchical-data using database MySql version 8.0.17
在 table t_contents
中存储了一个数据库 MySql version 8.0.17
我有这些行
+-------------------------+-------+-------+-----+
| Contents | sID_c | sID_p | sID |
+-------------------------+-------+-------+-----+
| Content 1 | 1 | NULL | 1 |
| - Gaio Giulio Cesare | 1 | NULL | 2 |
| Veni, vidi, vici. | 1 | NULL | 3 |
| Carpe diem. | 1 | NULL | 4 |
| Ubi maior minor cessat. | 1 | NULL | 5 |
| - Quinto Orazio Flacco | 1 | NULL | 6 |
| Condicio sine qua non. | 1 | NULL | 7 |
| Carthago delenda est. | 1 | NULL | 8 |
| Content 2 | 2 | NULL | 9 |
| - Marco Porcio Catone | 2 | NULL | 10 |
| Inter sidera versor. | 2 | NULL | 11 |
| Content 3 | 3 | NULL | 12 |
| - Marco Tullio Cicero | 3 | NULL | 13 |
| Vivere est cogitare | 3 | NULL | 14 |
+-------------------------+-------+-------+-----+
在 table t_contents 的列目录中:
Content 1
这是一个节
- Gaio Giulio Cesare
这是一章
-
Veni, vidi, vici
、Carpe diem.
和 Ubi maior minor cessat
。是第 章的段落
- 等...
不知道Section、Chapter和Chapter的段落数……都是变量……
我需要计算这些行并将这些行分组为 sID_c
字段,为此 return
mysql> SELECT
Contents,
COUNT(*) q
FROM
`t_contents`
GROUP BY
sID_c;
+-----------+----+
| Contents | q |
+-----------+----+
| Content 1 | 8 |
| Content 2 | 3 |
| Content 3 | 3 |
+-----------+----+
3 rows in set (0.02 sec)
并使用 q
值,最小值和最大值,return 此方案
+-------------------------+-------+-------+-----+
| Contents | sID_c | sID_p | sID |
+-------------------------+-------+-------+-----+
| Content 1 | 1 | 1.1 | 1 |
| - Gaio Giulio Cesare | 1 | 1.2 | 2 |
| Veni, vidi, vici. | 1 | 1.3 | 3 |
| Carpe diem. | 1 | 1.4 | 4 |
| Ubi maior minor cessat. | 1 | 1.5 | 5 |
| - Quinto Orazio Flacco | 1 | 1.6 | 6 |
| Condicio sine qua non. | 1 | 1.7 | 7 |
| Carthago delenda est. | 1 | 1.8 | 8 |
| Content 2 | 2 | 2.1 | 9 |
| - Marco Porcio Catone | 2 | 2.2 | 10 |
| Inter sidera versor. | 2 | 2.3 | 11 |
| Content 3 | 3 | 3.1 | 12 |
| - Marco Tullio Cicero | 3 | 3.2 | 13 |
| Vivere est cogitare | 3 | 3.3 | 14 |
+-------------------------+-------+-------+-----+
任何帮助将不胜感激...谢谢。
-- ----------------------------
-- Table structure for t_contents
-- ----------------------------
DROP TABLE IF EXISTS `t_contents`;
CREATE TABLE `t_contents` (
`Contents` varchar(255) DEFAULT NULL,
`sID_c` int(11) NULL DEFAULT NULL,
`sID_p` varchar(255) DEFAULT NULL,
`sID` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sID`) USING BTREE
) ENGINE = InnoDB;
-- ----------------------------
-- Records of t_contents
-- ----------------------------
INSERT INTO `t_contents` VALUES ('Content 1', 1, NULL, 1);
INSERT INTO `t_contents` VALUES ('- Gaio Giulio Cesare', 1, NULL, 2);
INSERT INTO `t_contents` VALUES ('Veni, vidi, vici.', 1, NULL, 3);
INSERT INTO `t_contents` VALUES ('Carpe diem.', 1, NULL, 4);
INSERT INTO `t_contents` VALUES ('Ubi maior minor cessat.', 1, NULL, 5);
INSERT INTO `t_contents` VALUES ('- Quinto Orazio Flacco', 1, NULL, 6);
INSERT INTO `t_contents` VALUES ('Condicio sine qua non.', 1, NULL, 7);
INSERT INTO `t_contents` VALUES ('Carthago delenda est.', 1, NULL, 8);
INSERT INTO `t_contents` VALUES ('Content 2', 2, NULL, 9);
INSERT INTO `t_contents` VALUES ('- Marco Porcio Catone', 2, NULL, 10);
INSERT INTO `t_contents` VALUES ('Inter sidera versor.', 2, NULL, 11);
INSERT INTO `t_contents` VALUES ('Content 3', 3, NULL, 12);
INSERT INTO `t_contents` VALUES ('- Marco Tullio Cicero', 3, NULL, 13);
INSERT INTO `t_contents` VALUES ('Vivere est cogitare', 3, NULL, 14);
您需要将 sID_c
与 ROW_NUMBER()
window 函数返回的数字连接起来:
SELECT Contents,
sID_c,
CONCAT(sID_c, '.', ROW_NUMBER() OVER (PARTITION BY sID_c ORDER BY sID)) sID_p,
sID
FROM t_contents
或者如果你想更新 table:
WITH cte AS (
SELECT CONCAT(sID_c, '.', ROW_NUMBER() OVER (PARTITION BY sID_c ORDER BY sID)) sID_p,
sID
FROM t_contents
)
UPDATE t_contents t
INNER JOIN cte c ON c.sID = t.sID
SET t.sID_p = c.sID_p
参见demo。
在 table t_contents
中存储了一个数据库 MySql version 8.0.17
我有这些行
+-------------------------+-------+-------+-----+
| Contents | sID_c | sID_p | sID |
+-------------------------+-------+-------+-----+
| Content 1 | 1 | NULL | 1 |
| - Gaio Giulio Cesare | 1 | NULL | 2 |
| Veni, vidi, vici. | 1 | NULL | 3 |
| Carpe diem. | 1 | NULL | 4 |
| Ubi maior minor cessat. | 1 | NULL | 5 |
| - Quinto Orazio Flacco | 1 | NULL | 6 |
| Condicio sine qua non. | 1 | NULL | 7 |
| Carthago delenda est. | 1 | NULL | 8 |
| Content 2 | 2 | NULL | 9 |
| - Marco Porcio Catone | 2 | NULL | 10 |
| Inter sidera versor. | 2 | NULL | 11 |
| Content 3 | 3 | NULL | 12 |
| - Marco Tullio Cicero | 3 | NULL | 13 |
| Vivere est cogitare | 3 | NULL | 14 |
+-------------------------+-------+-------+-----+
在 table t_contents 的列目录中:
Content 1
这是一个节- Gaio Giulio Cesare
这是一章-
Veni, vidi, vici
、Carpe diem.
和Ubi maior minor cessat
。是第 章的段落
- 等...
不知道Section、Chapter和Chapter的段落数……都是变量……
我需要计算这些行并将这些行分组为 sID_c
字段,为此 return
mysql> SELECT
Contents,
COUNT(*) q
FROM
`t_contents`
GROUP BY
sID_c;
+-----------+----+
| Contents | q |
+-----------+----+
| Content 1 | 8 |
| Content 2 | 3 |
| Content 3 | 3 |
+-----------+----+
3 rows in set (0.02 sec)
并使用 q
值,最小值和最大值,return 此方案
+-------------------------+-------+-------+-----+
| Contents | sID_c | sID_p | sID |
+-------------------------+-------+-------+-----+
| Content 1 | 1 | 1.1 | 1 |
| - Gaio Giulio Cesare | 1 | 1.2 | 2 |
| Veni, vidi, vici. | 1 | 1.3 | 3 |
| Carpe diem. | 1 | 1.4 | 4 |
| Ubi maior minor cessat. | 1 | 1.5 | 5 |
| - Quinto Orazio Flacco | 1 | 1.6 | 6 |
| Condicio sine qua non. | 1 | 1.7 | 7 |
| Carthago delenda est. | 1 | 1.8 | 8 |
| Content 2 | 2 | 2.1 | 9 |
| - Marco Porcio Catone | 2 | 2.2 | 10 |
| Inter sidera versor. | 2 | 2.3 | 11 |
| Content 3 | 3 | 3.1 | 12 |
| - Marco Tullio Cicero | 3 | 3.2 | 13 |
| Vivere est cogitare | 3 | 3.3 | 14 |
+-------------------------+-------+-------+-----+
任何帮助将不胜感激...谢谢。
-- ----------------------------
-- Table structure for t_contents
-- ----------------------------
DROP TABLE IF EXISTS `t_contents`;
CREATE TABLE `t_contents` (
`Contents` varchar(255) DEFAULT NULL,
`sID_c` int(11) NULL DEFAULT NULL,
`sID_p` varchar(255) DEFAULT NULL,
`sID` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sID`) USING BTREE
) ENGINE = InnoDB;
-- ----------------------------
-- Records of t_contents
-- ----------------------------
INSERT INTO `t_contents` VALUES ('Content 1', 1, NULL, 1);
INSERT INTO `t_contents` VALUES ('- Gaio Giulio Cesare', 1, NULL, 2);
INSERT INTO `t_contents` VALUES ('Veni, vidi, vici.', 1, NULL, 3);
INSERT INTO `t_contents` VALUES ('Carpe diem.', 1, NULL, 4);
INSERT INTO `t_contents` VALUES ('Ubi maior minor cessat.', 1, NULL, 5);
INSERT INTO `t_contents` VALUES ('- Quinto Orazio Flacco', 1, NULL, 6);
INSERT INTO `t_contents` VALUES ('Condicio sine qua non.', 1, NULL, 7);
INSERT INTO `t_contents` VALUES ('Carthago delenda est.', 1, NULL, 8);
INSERT INTO `t_contents` VALUES ('Content 2', 2, NULL, 9);
INSERT INTO `t_contents` VALUES ('- Marco Porcio Catone', 2, NULL, 10);
INSERT INTO `t_contents` VALUES ('Inter sidera versor.', 2, NULL, 11);
INSERT INTO `t_contents` VALUES ('Content 3', 3, NULL, 12);
INSERT INTO `t_contents` VALUES ('- Marco Tullio Cicero', 3, NULL, 13);
INSERT INTO `t_contents` VALUES ('Vivere est cogitare', 3, NULL, 14);
您需要将 sID_c
与 ROW_NUMBER()
window 函数返回的数字连接起来:
SELECT Contents,
sID_c,
CONCAT(sID_c, '.', ROW_NUMBER() OVER (PARTITION BY sID_c ORDER BY sID)) sID_p,
sID
FROM t_contents
或者如果你想更新 table:
WITH cte AS (
SELECT CONCAT(sID_c, '.', ROW_NUMBER() OVER (PARTITION BY sID_c ORDER BY sID)) sID_p,
sID
FROM t_contents
)
UPDATE t_contents t
INNER JOIN cte c ON c.sID = t.sID
SET t.sID_p = c.sID_p
参见demo。