나는 최근에 Nested Set Model에서 쓰레기를 사용 해왔다. 나는 모든 유용한 조작과 뷰를위한 쿼리 디자인을 즐겼다. 내가 붙어있는 한 가지 방법은 바로 밑의 자식을 선택하는 것입니다 (그리고 자식들, 더 이상의 자손은 아닙니다!).노드의 하위 항목을 쿼리하는 간단한 방법이 있습니까?
솔직히 말해서 나는 방법을 알고 있지만 관리하기 어려운 양의 SQL이 관련되어 있습니다. 좀 더 간단한 해결책이 있다고 확신합니다.
나는 최근에 Nested Set Model에서 쓰레기를 사용 해왔다. 나는 모든 유용한 조작과 뷰를위한 쿼리 디자인을 즐겼다. 내가 붙어있는 한 가지 방법은 바로 밑의 자식을 선택하는 것입니다 (그리고 자식들, 더 이상의 자손은 아닙니다!).노드의 하위 항목을 쿼리하는 간단한 방법이 있습니까?
솔직히 말해서 나는 방법을 알고 있지만 관리하기 어려운 양의 SQL이 관련되어 있습니다. 좀 더 간단한 해결책이 있다고 확신합니다.
게시 한 기사를 읽었습니까? 나는 테이블에서 "PARENT_ID"를 포함 - 그것은 내가 (이 부정 행위) 할 것은 내가 인접리스트와 중첩 된 세트를 결합, 제목 그러나
SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
nested_category AS parent,
nested_category AS sub_parent,
(
SELECT node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'PORTABLE ELECTRONICS'
GROUP BY node.name
ORDER BY node.lft
)AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth <= 1
ORDER BY node.lft;
"노드의 즉시 부하 직원 찾기"아래의 , 그래서 나는 노드의 자식들에게 쉽게 물어볼 수있다.
하위 쿼리 또는 상위 열 중복이 없으면 쉽게 수행 할 수 있습니다! 예를 들어, 주어진 부모의 왼쪽과 오른쪽은 이미 알려져 있습니다
입니다SELECT child.id
FROM nodes AS child
LEFT JOIN nodes AS ancestor ON
ancestor.left BETWEEN @parentleft+1 AND @parentright-1 AND
child.left BETWEEN ancestor.left+1 AND ancestor.right-1
WHERE
child.left BETWEEN @parentleft+1 AND @parentright-1 AND
ancestor.id IS NULL
, "문제의 노드의 모든 후손으로부터는 자신과 노드 사이에 조상과 사람을 선택".
성능면에서 어느 대답이 더 좋은지 궁금합니다. 그러나 두 솔루션 모두 작동합니다. 이것은 좀 더 조밀 해 보입니다. – andreas
매우 큰 나무의 경우 데이터베이스에서 중첩 루프를 수행해야하기 때문에 MySQL에서 성능이 떨어지고 SQL 서버에서 성능이 떨어지는 것을 발견했습니다. 우리는 코드를 변경하여 모든 자손을 검색 한 다음 응용 프로그램 코드에서 자손으로 정리합니다. – user393274
@andreas 이것은 받아 들인 대답과 매우 흡사합니다. 차이점은 자식을 세고 자식이 1 인 자식으로 필터링하는 대신 조상이 NULL인지 확인하여 필터링합니다. 즉, 정렬 작업이 적고 카운트 단계). 속도는 빨라야하지만 테스트하지는 않았습니다. – Ariel
는이 하나 더
사용자 "bobince는"거의 있었다 작다. 내가 알아 낸 것이고, MySQL보다 약간의 MySQL 경험이 있기 때문에 나에게 효과가있다. 그러나, 나는 왜 bobince의 대답이 사람들을 놀라게 할지를 알 수 있습니다. 그의 질문은 불완전하다. 먼저 mysql 변수에 parent_left와 parent_right를 선택해야합니다.
아래의 두 쿼리는 테이블이 오른쪽 열에는 rgt
라는 및 기본 키가 id
라는 것을, 당신의 왼쪽 열이 lft
라는, tree
라는 가정합니다. 필요에 맞게이 값을 변경하십시오. 또한 첫 번째 select 문을 검사하십시오. 노드 5의 바로 후손을 찾고있는 것을 볼 수 있습니다. 원하는 노드의 자식을 찾기 위해 숫자 5를 변경하십시오.
저는 개인적으로 이것은 지금까지 제시된 것보다 더 매끄럽고 섹시하며 효율적인 쿼리라고 생각합니다.
SELECT `lft`, `rgt` INTO @parent_left, @parent_right FROM efm_files WHERE `id` = 5;
SELECT `child`.`id`
FROM `tree` AS `child`
LEFT JOIN `tree` AS `ancestor` ON
`ancestor`.`lft` BETWEEN @parent_left+1 AND @parent_right-1 AND
`child`.`lft` BETWEEN `ancestor`.`lft`+1 AND `ancestor`.`rgt`-1
WHERE
`child`.`lft` BETWEEN @parent_left+1 AND @parent_right-1 AND
`ancestor`.`id` IS NULL
'efm_files '이란 무엇입니까? – Madbreaks
efm_files는 mysql 데이터베이스에있는 테이블의 이름입니다. 데이터베이스의 고유 한 테이블 이름으로 바꾸십시오. – mrbinky3000
저는 necro 게시물을 쓰는 것을 알고 있습니다. 하지만 제 의견은 여기에 있습니다.
중첩 된 집합에 "깊이"열을 포함하지 않는 이유는 무엇입니까? 깊이 열은 항목의 "수준"을 나타냅니다. 그래서
는, 너무,select c.*
from tree as p
join tree as c on (c.left > p.left and c.right < p.right and c.depth = p.dept + 1) where p.id = @parentID
엄격하게 말해서 더 이상 중첩 된 집합이 아니기 때문에 계층 적 모델의 조합입니다. 그리고 종종 문제를 해결하기 위해 모델을 변경하는 것은 선택 사항이 아닙니다. – Madbreaks
내가 깊이 열이 가고 싶어 할, 항목의 즉각적인 차일을 선택합니다. 하지만 Wikipedia link가 선택한 답변과 함께 답변의 좋은 최소화 버전이 발견
SELECT Child.Node, Child.LEFT, Child.RIGHT
FROM Tree AS Child, Tree AS Parent
WHERE
Child.Depth = Parent.Depth + 1
AND Child.LEFT > Parent.LEFT
AND Child.RIGHT < Parent.RIGHT
AND Parent.LEFT = 1 -- Given Parent Node Left Index
왼쪽 및 오른쪽 ID와 함께 * 추가 * 깊이 열이 필요합니다. – Youngjae
사용합니다.
SELECT DISTINCT Child.Name
FROM ModelTable AS Child, ModelTable AS Parent
WHERE Parent.Lft < Child.Lft AND Parent.Rgt > Child.Rgt -- associate Child Nodes with ancestors
GROUP BY Child.Name
HAVING MAX(Parent.Lft) = @parentId -- Subset for those with the given Parent Node as the nearest ancestor
, 당신의 LINQ에 그것을 표현하려고하면 링크를 클릭하십시오 : https://stackoverflow.com/a/25594386/361100
를 "... 내가 ... 인접리스트와 중첩 된 세트를 결합"하! 그게 내가하고있는 일이야. 나는 adj. 조 Celko에 의해 쿼리를 기반으로 목록보기. 그것은 엄청난 양의 코드처럼 보입니다. 심지어 링크 된 기사의 솔루션은 ... 장황하다. – Metaphile
내 말은, 노드의 자손을 _all_을 선택하는 것과 비교하면 다음과 같습니다. SELECT * 노드에서 where nodes.leftBound BETWEEN parentLeftBound AND parentRightBound; – Metaphile
음, "child_view"는 매우 간단합니다. SELECT * FROM nodes parent_id = 123456 : D –