mysql递归自联接

Jam*_*mes 1 mysql recursion self-join

create table test(
container varchar(1),
contained varchar(1)
);

insert into test values('X','A');
insert into test values('X','B');
insert into test values('X','C');
insert into test values('Y','D');
insert into test values('Y','E');
insert into test values('Y','F');
insert into test values('A','P');
insert into test values('P','Q');
insert into test values('Q','R');
insert into test values('R','Y');
insert into test values('Y','X');

select * from test;

    mysql> select * from test;
    +-----------+-----------+
    | container | contained |
    +-----------+-----------+
    | X         | A         |
    | X         | B         |
    | X         | C         |
    | Y         | D         |
    | Y         | E         |
    | Y         | F         |
    | A         | P         |
    | P         | Q         |
    | Q         | R         |
    | R         | Y         |
    | Y         | X         |
    +-----------+-----------+
    11 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

我可以distinct使用单个自联接找出"X"下包含的所有值吗?

EDIT

比如,这里X包含A,B和C A包含P P包含Q Q包含R R包含Y Y包含C,D和E ...

所以当我查询X时,我想显示A,B,C,D,E,P,Q,R,Y.

EDIT

通过编程做到了.

package com.catgen.helper;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.catgen.factories.Nm2NmFactory;

public class Nm2NmHelper {
    private List<String> fetched;
    private List<String> fresh;

    public List<String> findAllContainedNMByMarketId(Connection conn, String marketId) throws SQLException{
        fetched = new ArrayList<String>();
        fresh = new ArrayList<String>();
        fresh.add(marketId.toLowerCase());
        while(fresh.size()>0){
            fetched.add(fresh.get(0).toLowerCase());
            fresh.remove(0);
            List<String> tempList = Nm2NmFactory.getContainedNmByContainerNm(conn, fetched.get(fetched.size()-1));
            if(tempList!=null){
                for(int i=0;i<tempList.size();i++){
                    String current = tempList.get(i).toLowerCase();
                    if(!fetched.contains(current) && !fresh.contains(current)){
                        fresh.add(current);
                    }
                }
            }
        }
        return fetched;
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然不是同一个表和字段.但我希望你能得到这个概念.多谢你们.

Mar*_*ers 7

您无法使用与该数据结构的单个连接递归地获取所有包含的对象.你需要一个递归查询,但MySQL还不支持.

但是,您可以构造一个闭包表,然后您可以使用简单的查询来完成它.有关更多详细信息和其他方法(例如,嵌套集),请参阅Bill Karwin的幻灯片模型中的层次数据.幻灯片69比较了不同的设计,以便于实现"查询子树".您选择的设计(邻接列表)是此类查询的所有四种设计中最尴尬的.