2012-10-26 5 views
2

CTE를 사용하여 계층 구조를 탐색하려고하는데 한 시나리오에서는 제대로 작동하지만 다른 시나리오에서는 제대로 작동하지 않습니다.아무 것도 발견되지 않으면 다음 결과 찾기?

주어진 쿼리.

BoM이 bom_id 열의 하위 boms로 드릴 다운하기 때문에 예상 한대로 쿼리가 작동합니다. 아이 BOM에가 발견되지 않는 경우

코드에서 (OpenERP에서), (더 bom_id) 아이 제품은 PRODUCT_ID에 따라 검색되지 않습니다 :

sids = bom_obj.search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)]) 

방법 I가 있는지 궁금하고 SQL에서 동일한 것을 수행하는 데 사용할 수 있습니다. CTE가 행을 반환하지 않으면 product_id 및 null bom_id로 확인하십시오. 나는 다른 재귀 회원에 대해서 생각해 보았지만 그것이 내가 찾고있는 것이라고는 생각하지 않는다.

제 질문에 대한 답은 분명하지 않지만, 어떤 제안이 있습니까? 여기

SQL 바이올린 예 데이터 : 그것은 결코 논리적으로 종료하기 때문에 http://sqlfiddle.com/#!3/b9052/1

답변

1

이유 HABO이 on b.bom_id = cte.ID or (b.bom_id is NULL and b.product_id = cte.product_id)을 제안하고 당신이 이미 작동하지 않는 노력으로 다음과 같은 노력하는 이유입니다.

그러나 자식이 발견되지 않으면 한 번 종료하는 종료식이 있습니다. 그것은 가능하다 : 것과 가장 쉬운 방법은

WHERE NOT EXISTS (SELECT * FROM BOMcte bc WHERE b.id = bc.PARENTASSEMBLYID) 

전체 SQL

;WITH BOMcte (ID, Code, BomName , ProductID, ProductCode, ProductName , ParentAssemblyID) 
AS 
(
    SELECT b.id, 
      b.code, 
      b.name, 
      p.id, 
      p.default_code, 
      p.name_template, 
      b.bom_id 

    FROM mrp_bom AS b 
    INNER JOIN product_product p on b .product_id = p.id  
    WHERE b. bom_id IS NULL 
    and b.id = @AssemblyID 
    UNION ALL 
    SELECT b.id, 
      b.code, 
      b.name, 
      p.id, 
      p.default_code, 
      p.name_template, 
      b.bom_id 
    FROM mrp_bom AS b 
    INNER JOIN product_product p on b .product_id = p.ID  
    INNER JOIN BOMcte AS cte ON b.bom_id = cte.ID  
) 
SELECT * FROM BOMcte 
UNION 

SELECT b.id, 
      b.code, 
      b.name, 
      p.id, 
      p.default_code, 
      p.name_template, 
      b.bom_id 

    FROM mrp_bom AS b 
    INNER JOIN product_product p on b.product_id = p.id 
    WHERE NOT EXISTS (SELECT * FROM BOMcte bc WHERE b.id = bc.PARENTASSEMBLYID) 

SQL DEMO

주 BOMcte의 행은 자식이없는 것을 확인하기 위해 확인하는 UNION을 추가하는 것입니다 재귀 쿼리에서 MSDN article에있는 것과 같이 증가하는 LEVEL 값을 사용하여 CTE에서 종료 표현식을 인코딩합니다.

+0

그렇지 않습니다. 중복 하위 행을 리턴합니다. – ehcanadian

+0

나는 어디에도 존재하지 않는다고 의심한다. (SELECT * FROM mrp_bom mb WHERE mb.bom_id = b.ID)'샘플 데이터를 만들 수 있습니까? [SQL 피들] (http://sqlfiddle.com/)도 좋을 것입니다. –

+0

도움이 되나요? 전에 SQL Fiddle을 사용하지 않았습니다. http://sqlfiddle.com/#!3/b9052/1 (편집 된 URL) – ehcanadian

0

저는 조금 u입니다. 당신이하려고하는 것에 대해 nclear하지만 최종 참여를 위해 다음과 같이 할 수 있습니다 :

on b.bom_id = cte.ID or (b.bom_id is NULL and b.product_id = cte.product_id) 
+0

그게 정확히 내가 뭘하려고하고 언급 한 조건을 추가하려고했지만 maxrecursion 제한을 누르십시오. (제품 ID에서 반복됩니다.) – ehcanadian

+0

[MAXRECURSION] (http://msdn.microsoft.com/en-us/library/ms181714.aspx) 쿼리 힌트를 사용하여 재귀 제한을 늘리거나 제거 할 수 있습니다. 주기에 멈추지 않았습니까? BoM과 제품 사이를왔다 갔다합니까? – HABO

관련 문제