[英]Self-referencing table Query
I have a table called commitments where the primary key is commit_no
and a self referencing column in called commit_rollup_no
.我有一个名为commit_no
的表,其中主键是commit_no
和一个名为commit_rollup_no
的自引用列。 My goal is to be able to pull back all the referenced tabled based on the highest commit_no
.我的目标是能够根据最高的commit_no
拉回所有引用的commit_no
。
Example例子
commit_no | commit_rollup_no
---------------------------
1 null
2 1
3 1
4 2
5 3
6 5
7 6
Desired Result:预期结果:
for all commitments that rollup to commit_no 1对于汇总到 commit_no 1 的所有承诺
2,3,4,5,6,7
for all commitments that rollup to commit_no 2对于汇总到 commit_no 2 的所有承诺
4
for all commitments that rollup to commit_no 3对于汇总到 commit_no 3 的所有承诺
5,6,7
I was wondering how someone with more experiencing with self-referring tables might tackle this query.我想知道对自引用表有更多经验的人如何处理这个查询。 In some cases it might go 100 levels deep and the requirement is to get all the associated commitments back.在某些情况下,它可能会深入 100 个级别,而要求是收回所有相关的承诺。
Would this work out for you?这对你有用吗?
SELECT `commit_no`,
(SELECT Group_concat(`commit_no`)
FROM `commits` `c`
WHERE `c`.`commit_rollup_no` = `com`.`commit_no`) AS `SubCommits`
FROM `commits` AS `com`
MySQL 5.6 Schema Setup : MySQL 5.6 架构设置:
CREATE TABLE commits
(`commit_no` int, `commit_rollup_no` int)
;
INSERT INTO commits
(`commit_no`, `commit_rollup_no`)
VALUES
(1, 0),
(2, 1),
(3, 1),
(4, 2),
(5, 3),
(6, 5),
(7, 6)
;
Query 1 :查询 1 :
SELECT `commit_no`, (SELECT GROUP_CONCAT(`commit_no`) FROM `commits` `c` WHERE `c`.`commit_rollup_no` = `com`.`commit_no`) AS `SubCommits` FROM `commits` AS `com`
+-----------+------------+
| commit_no | SubCommits |
+-----------+------------+
| 1 | 2,3 |
| 2 | 4 |
| 3 | 5 |
| 4 | (null) |
| 5 | 6 |
| 6 | 7 |
| 7 | (null) |
+-----------+------------+
CREATE DEFINER=`IDPAdmin`@`%` FUNCTION `CommitChildren`(ParentCommit INT) RETURNS varchar(1024) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE rv,q,queue,queue_children VARCHAR(1024);
DECLARE queue_length,front_id,pos INT;
SET rv = '';
SET queue = ParentCommit;
SET queue_length = 1;
WHILE queue_length > 0 DO
IF queue_length = 1 THEN
SET front_id = queue;
SET queue = '';
ELSE
SET front_id = SUBSTR(queue,1,LOCATE(',',queue)-1);
SET pos = LOCATE(',',queue) + 1;
SET q = SUBSTR(queue,pos);
SET queue = q;
END IF;
SET queue_length = queue_length - 1;
SELECT IFNULL(qc,'') INTO queue_children
FROM (SELECT GROUP_CONCAT(commit_no) qc
FROM commitments WHERE commit_rollup_no = front_id) A;
IF LENGTH(queue_children) = 0 THEN
IF LENGTH(queue) = 0 THEN
SET queue_length = 0;
END IF;
ELSE
IF LENGTH(rv) = 0 THEN
SET rv = queue_children;
ELSE
SET rv = CONCAT(rv,',',queue_children);
END IF;
IF LENGTH(queue) = 0 THEN
SET queue = queue_children;
ELSE
SET queue = CONCAT(queue,',',queue_children);
END IF;
SET queue_length = LENGTH(queue) - LENGTH(REPLACE(queue,',','')) + 1;
END IF;
END WHILE;
RETURN rv;
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.