2014-11-18 1 views
1

SQL - (루프처럼) 모든 전제 조건을 나열

좋아 내 데이터베이스 구조가이 비슷합니다 (I가 너무 많이 중요 것이라고 생각하지는 않지만 저는 SQL 플러스를 사용하고 있습니다) :

CREATE TABLE MODULE (
    module_code  INT, 
    PRIMARY KEY (module_code) 
); 

CREATE TABLE PREREQUISITES (
    module_code  INT, 
    prerequisite_code VARCHAR(6), 
    FOREIGN KEY (module_code) REFERENCES MODULE(module_code), 
    FOREIGN KEY (prerequisite_code) REFERENCES MODULE(module_code) 
); 

그래서 데이터는 다음과 같이 보일 수 있습니다 :

MODULE: 
5 
15 
20 
100 

PREREQUISITES: 
100 20 
100 15 
15 5 

내 질문이있는 모듈에 대한 모든 전제 조건 (100의 예 전제 조건을 나열 할 수있는 방법이된다 : 20, 15이있다 (15) & 5 (때문에 홍보 5)의 필수 조건을 충족 시키거나이를 프로그래밍 방식으로 수행해야합니다.

순환 참조가있을 수도 있음을 알고 있습니다. 다시 프로그래밍 방식으로이 작업을 수행하는 방법을 생각할 수 있지만 SQL을 사용하여이를 감지하는 방법이 있습니다.

+1

그들은 본질적에서 사람을 방지하고 있기 때문에, 관계를 설계 한 사람들이 때리기 필요를 생태계 내의 모든 것을 배우고 다른 사람들에게 간접적으로 배울 것을 요구합니다. sgeddes는 좋은 대답을 가지고있다. – Spade

+0

어떻게 그런 테이블을 만들어야하는지 추천 해 주겠다. –

답변

2

실제로, 사용하고있는 RDBMS는 달성하려는 작업에 완전히 일치합니다. 계층 구조 데이터를 adjacency list 모델에 저장하고 있습니다. 당신이 oracle을 사용하고 있기 때문에, 당신은 나무 통과 할 CONNECT BY를 사용할 수 있습니다

SELECT * 
FROM PREREQUISITES 
START WITH module_code = 100 
CONNECT BY module_code = PRIOR prerequisite_code 

을 그리고 여기에 주제에 대한 좋은 기사입니다 : http://explainextended.com/2009/09/28/adjacency-list-vs-nested-sets-oracle/


중복 된 경우 및 무한 루프가 잠재적 인 우려 사항이므로 nocylcle을 사용하면 무한 루프를 방지 할 수 있습니다. ITE 루프와 서브 쿼리는 distinct 결과를 반환 :

SELECT * 
FROM (SELECT DISTINCT module_code, prerequisite_code FROM PREREQUISITES) T 
START WITH module_code = 100 
CONNECT BY NOCYCLE module_code = PRIOR prerequisite_code 
+0

어떻게하면 NOCYCLE과 DISTINCT를 가져 와서 루프를 막을 수 있습니까? – Spade

+0

@Spade - 확실하고 좋은 점. 업데이트 된 피들 : http://sqlfiddle.com/#!4/e345e/2 – sgeddes

+0

나는 이것을 배웠지 않았다! 감사. MySQL에서 비슷한 기능이 나타날 수 있습니다. 또한 바닐라 SQL을 사용하여 가능합니다. –