简体   繁体   English

自引用表查询

[英]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`

SQL Fiddle SQL小提琴

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`

Results :结果

+-----------+------------+
| 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM