MySQL рекурсивное самостоятельное соединение - PullRequest
1 голос
/ 11 августа 2010
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)

Могу ли я узнать все значения distinct, содержащиеся в 'X', с помощью одного самостоятельного соединения?

EDIT

Как и здесь Х содержит А, В и С А содержит Р P содержит Q Q содержит R R содержит Y Y содержит C, D и E ...

Поэтому я хочу отображать A, B, C, D, E, P, Q, R, Y, когда я запрашиваю X.

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;
    }
}

Не та же таблица и поля, хотя. Но я надеюсь, что вы поняли концепцию. Спасибо, ребята.

Ответы [ 2 ]

7 голосов
/ 11 августа 2010

Вы не можете получить все содержащиеся объекты рекурсивно, используя одно соединение с этой структурой данных. Вам потребуется рекурсивный запрос, но MySQL пока не поддерживает это.

Однако вы можете построить таблицу замыканий, а затем сделать это простым запросом. См. Слайд-шоу Билла Карвина Модели для иерархических данных для получения дополнительной информации и других подходов (например, вложенных наборов). На слайде 69 сравниваются различные проекты для упрощения реализации «Поддерева запросов». Выбранный вами дизайн (список смежности) - самый неудобный из всех четырех проектов для этого типа запроса.

0 голосов
/ 11 августа 2010

Как насчет чтения всей таблицы в массив php и определения потомков через.функция, которая будет вызывать себя?

Но это не очень хорошее решение, если в таблице более 10000 строк ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...