2013-04-17 1 views
0

게시물에 중첩 된 의견이 첨부 된 앱을 설정했습니다. 나는 나무 구조를 질의하고 관리하는 것이 얼마나 쉬운 지와 비교할 때 하드 디스크 공간이 얼마나 싼지에 대한 의견으로 closure table 방법 (슬라이드 40)을 사용하기로 결정했습니다. 그러나 나는 문제가있다. 조상 ID (슬라이드 49)가 아닌 게시 ​​ID를 기반으로 트리 경로를 잡는 방법을 알아낼 수 없습니다.JOIN을 사용하여 클로저 테이블에서 SELECT 쿼리를 실행 하시겠습니까?

table: comment_paths 
-------------------- 
parent_id (fk on comments.id) 
child_id (fk on comments.id) 
depth 

table: comments 
--------------- 
id 
parent_id (fk on comments.id) 
post_id (fk on posts.id) 
text 

table: posts 
--------------- 
id 
name 

, 그것은 나무 잡아 간단 슬라이드 쇼처럼 내가 미리 PARENT_ID를 알고있는 경우 : 그러나

SELECT c.*, p.* 
FROM comments AS c 
JOIN comment_paths AS p 
ON c.id = p.child_id 
WHERE p.parent_id = 1 

을, 그렇게하지

내 데이터베이스 구조는 다음과 같습니다 미리 parent_id을 알고 있어야합니다. 나는 post_id만을 알고 있습니다.

    [post] 
----------------------------------------- 
[comment]  [comment]  [comment] depth: 0 
    |        | 
[reply]       [reply] depth: 1 
    | | 
[r] [r]         depth: 2 

내 초기 솔루션은이 같은 쿼리했다 : 데이터베이스를 설정하는 방법은, 하나 이상의 나무가 게시물과 관련된 올바른 데이터를 반환

SELECT c.*, p.* 
FROM comments AS c 
JOIN comment_paths AS p 
ON c.id = p.child_id 
WHERE p.parent_id IN 
    (SELECT id FROM comments WHERE parent_id IS NULL AND post_id = 6) 

,하지만 난 중첩 된 SELECT 같은 느낌이 정확하지 않습니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

감사합니다.

+0

이 쿼리'SELECT C를 시도 * P * 의견 FROM 이 페이지 AS comment_paths 가입하세요 C AS. ON c.id = p.parent_id c.parent_id가 NULL이고 c.post_id = 6' – Meherzad

+0

@Meherzad가 작동하지 않았습니다. :(단지 나무의 꼭대기를 돌려주었습니다.) – Patrick

답변

2

나는 더 좋은 방법을 생각할 수 없다. 내가 할 수있는 유일한 변화는 IN 대신 EXISTS를 사용하는 것입니다.

SELECT c.*, p.* 
FROM comments AS c 
JOIN comment_paths AS p 
ON c.id = p.child_id 
WHERE EXISTS 
(SELECT * FROM comments c2 WHERE p.parent_id = c2.id AND c2.parent_id IS NULL AND c2.post_id = 6) 

실제로 더 좋은 방법이 있는지 알고 싶습니다.

업데이트 :

사용중인 RDMS가 확실하지 않습니다. 재귀 쿼리를 사용할 수있는 경우 그러나, 당신이 떨어져 완전히 comments_path 테이블에서 얻을 수있는 생각하고있다 :.

;with cte as(
select c.*, 0 as depth 
from comments c 
where c.post_id = 6 and c.parent_id is null 
union all 
select c.*, cte.depth + 1 
from comments c 
join cte on c.parent_id = cte.id) 

select * from cte 
+0

답변 해 주셔서 감사합니다. 'EXISTS'와'IN'을 사용할 이유가 있습니까? 그것을 대체하면 매우 다른 데이터 세트가 반환됩니다. 코멘트 세트 대신에 comment_paths 세트에 기록하십시오. – Patrick

+0

다른 결과 세트는 "p.child_id"대신 "= p.parent_id"를 가졌기 때문에 타이핑이 필요했습니다. 내 경험으로는 EXISTS가 더 잘 수행됩니다 어떤 경우에는 성능이 향상되지 않을 수도 있지만 IN보다 좋지 않은 경우 항상 수행해야합니다. –

+0

방금 ​​재귀 쿼리를 업데이트 한 것으로 보았습니다. 그것을 제공하는 RDMS는 클로저 테이블보다 빠르지 만, 가능한 한 많은 RDMS에서 실행할 수 있고 버그를 최소한으로 유지하기 위해 RDMS 관련 쿼리를 피할 수 있기를 바랍니다. 업데이트, 그래도! – Patrick