2010-08-11 4 views
1
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', используя единое самостоятельное соединение?mysql recursive self join

EDIT

Мол, здесь Х содержит А, В и С А содержит Р Р содержит 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; 
    } 
} 

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

ответ

7

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

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

+0

Отличный ресурс! Ты просто спас мне здравый смысл. – Rustavore

0

Что касается чтения всей таблицы в php-массив и определения дочерних элементов. функцию, которая называла бы себя?

Но это нехорошее решение, если таблица имеет более 10000 рядов ...