2013-10-02 1 views
1
나는 다음과 같은 쿼리를 시도하고있어

,외부 조인을 사용한 재귀 쿼리?

DECLARE @EntityType varchar(25) 
SET @EntityType = 'Accessory'; 

WITH Entities (
     E_ID, E_Type, 
     P_ID, P_Name, P_DataType, P_Required, P_OnlyOne, 
     PV_ID, PV_Value, PV_EntityID, PV_ValueEntityID, 
     PV_UnitValueID, PV_UnitID, PV_UnitName, PV_UnitDesc, PV_MeasureID, PV_MeasureName, PV_UnitValue, 
     PV_SelectionID, PV_DropDownID, PV_DropDownName, PV_DropDownOptionID, PV_DropDownOptionName, PV_DropDownOptionDesc, 
     RecursiveLevel 
    ) 
AS 
(
    -- Original Query 
    SELECT dbo.Entity.ID AS E_ID, dbo.EntityType.Name AS E_Type, 
    dbo.Property.ID AS P_ID, dbo.Property.Name AS P_Name, DataType.Name AS P_DataType, Required AS P_Required, OnlyOne AS P_OnlyOne, 
    dbo.PropertyValue.ID AS PV_ID, dbo.PropertyValue.Value AS PV_Value, dbo.PropertyValue.EntityID AS PV_EntityID, dbo.PropertyValue.ValueEntityID AS PV_ValueEntityID, 
    dbo.UnitValue.ID AS PV_UnitValueID, dbo.UnitOfMeasure.ID AS PV_UnitID, dbo.UnitOfMeasure.Name AS PV_UnitName, dbo.UnitOfMeasure.Description AS PV_UnitDesc, dbo.Measure.ID AS PV_MeasureID, dbo.Measure.Name AS PV_MeasureName, dbo.UnitValue.UnitValue AS PV_UnitValue, 
    dbo.DropDownSelection.ID AS PV_SelectionID, dbo.DropDown.ID AS PV_DropDownID, dbo.DropDown.Name AS PV_DropDownName, dbo.DropDownOption.ID AS PV_DropDownOptionID, dbo.DropDownOption.Name AS PV_DropDownOptionName, dbo.DropDownOption.Description AS PV_DropDownOptionDesc, 
    0 AS RecursiveLevel 
    FROM dbo.Entity 
    INNER JOIN dbo.EntityType ON dbo.EntityType.ID = dbo.Entity.TypeID 
    INNER JOIN dbo.Property ON dbo.Property.EntityTypeID = dbo.Entity.TypeID 
    INNER JOIN dbo.PropertyValue ON dbo.Property.ID = dbo.PropertyValue.PropertyID AND dbo.PropertyValue.EntityID = dbo.Entity.ID 
    INNER JOIN dbo.DataType ON dbo.DataType.ID = dbo.Property.DataTypeID 
    LEFT JOIN dbo.UnitValue ON dbo.UnitValue.ID = dbo.PropertyValue.UnitValueID 
    LEFT JOIN dbo.UnitOfMeasure ON dbo.UnitOfMeasure.ID = dbo.UnitValue.UnitOfMeasureID 
    LEFT JOIN dbo.Measure ON dbo.Measure.ID = dbo.UnitOfMeasure.MeasureID 
    LEFT JOIN dbo.DropDownSelection ON dbo.DropDownSelection.ID = dbo.PropertyValue.DropDownSelectedID 
    LEFT JOIN dbo.DropDownOption ON dbo.DropDownOption.ID = dbo.DropDownSelection.SelectedOptionID 
    LEFT JOIN dbo.DropDown ON dbo.DropDown.ID = dbo.DropDownSelection.DropDownID 
    WHERE dbo.EntityType.Name = @EntityType 
    UNION ALL 
    -- Recursive Query? 
    SELECT E2.E_ID AS E_ID, dbo.EntityType.Name AS E_Type, 
    dbo.Property.ID AS P_ID, dbo.Property.Name AS P_Name, DataType.Name AS P_DataType, Required AS P_Required, OnlyOne AS P_OnlyOne, 
    dbo.PropertyValue.ID AS PV_ID, dbo.PropertyValue.Value AS PV_Value, dbo.PropertyValue.EntityID AS PV_EntityID, dbo.PropertyValue.ValueEntityID AS PV_ValueEntityID, 
    dbo.UnitValue.ID AS PV_UnitValueID, dbo.UnitOfMeasure.ID AS PV_UnitID, dbo.UnitOfMeasure.Name AS PV_UnitName, dbo.UnitOfMeasure.Description AS PV_UnitDesc, dbo.Measure.ID AS PV_MeasureID, dbo.Measure.Name AS PV_MeasureName, dbo.UnitValue.UnitValue AS PV_UnitValue, 
    dbo.DropDownSelection.ID AS PV_SelectionID, dbo.DropDown.ID AS PV_DropDownID, dbo.DropDown.Name AS PV_DropDownName, dbo.DropDownOption.ID AS PV_DropDownOptionID, dbo.DropDownOption.Name AS PV_DropDownOptionName, dbo.DropDownOption.Description AS PV_DropDownOptionDesc, 
    (RecursiveLevel + 1) 
    FROM Entities AS E2 
    INNER JOIN dbo.Entity ON dbo.Entity.ID = E2.PV_ValueEntityID 
    INNER JOIN dbo.EntityType ON dbo.EntityType.ID = dbo.Entity.TypeID 
    INNER JOIN dbo.Property ON dbo.Property.EntityTypeID = dbo.Entity.TypeID 
    INNER JOIN dbo.PropertyValue ON dbo.Property.ID = dbo.PropertyValue.PropertyID AND dbo.PropertyValue.EntityID = E2.E_ID 
    INNER JOIN dbo.DataType ON dbo.DataType.ID = dbo.Property.DataTypeID 
    INNER JOIN dbo.UnitValue ON dbo.UnitValue.ID = dbo.PropertyValue.UnitValueID 
    INNER JOIN dbo.UnitOfMeasure ON dbo.UnitOfMeasure.ID = dbo.UnitValue.UnitOfMeasureID 
    INNER JOIN dbo.Measure ON dbo.Measure.ID = dbo.UnitOfMeasure.MeasureID 
    INNER JOIN dbo.DropDownSelection ON dbo.DropDownSelection.ID = dbo.PropertyValue.DropDownSelectedID 
    INNER JOIN dbo.DropDownOption ON dbo.DropDownOption.ID = dbo.DropDownSelection.SelectedOptionID 
    INNER JOIN dbo.DropDown ON dbo.DropDown.ID = dbo.DropDownSelection.DropDownID 

) 
SELECT E_ID, E_Type, 
    P_ID, P_Name, P_DataType, P_Required, P_OnlyOne, 
    PV_ID, PV_Value, PV_EntityID, PV_ValueEntityID, 
    PV_UnitValueID, PV_UnitID, PV_UnitName, PV_UnitDesc, PV_MeasureID, PV_MeasureName, PV_UnitValue, 
    PV_SelectionID, PV_DropDownID, PV_DropDownName, PV_DropDownOptionID, PV_DropDownOptionName, PV_DropDownOptionDesc, 
    RecursiveLevel 
FROM Entities 
INNER JOIN [dbo].[Entity] AS dE 
    ON dE.ID = PV_EntityID 

문제는 두 번째 쿼리는 "재귀 하나"입니다 나는 좌 첫 번째 쿼리에서 같은 조인 할 수 없기 때문에 내가 기대하는 데이터를 얻고있다. (적어도 내 이해에).

LEFT (외부) JOIN이 필요한 데이터를 가져 오지 않으면 재귀가 완벽하게 작동합니다. 내 문제는 둘 다 필요하다. 이 일을 성취 할 수있는 방법이 있습니까?

답변

3

http://msdn.microsoft.com/en-us/library/ms175972.aspx은 재귀 CTE에서 왼쪽/오른쪽/외부 조인을 가질 수 없습니다.

재귀 CTE의 경우 하위 쿼리를 사용할 수 없으므로 this example 다음에 sugest를 사용합니다.

두 개의 CTE를 사용합니다. 첫 번째 클래스는 재귀 적이 지 않으며 왼쪽에있는 함수가 필요한 데이터를 가져 오기 위해 조인합니다. 두 번째 CTE는 첫 번째 CTE에서 재귀 및 내부 조인입니다. CTE1은 재귀 적이 지 않기 때문에 누락 된 행에 대한 조인과 디폴트 값을 제공 할 수 있으며 내부 조인에서 작업해야합니다.

그러나 일반적으로 정말 유용하지는 않지만 유니온과 서브 선택으로 왼쪽 조인을 복제 할 수도 있지만 흥미 롭습니다.

이 경우, 어떻게 작성했는지 처음으로 설명 할 수 있습니다. 성공적으로 조인 한 모든 행과 일치합니다.

조인을 제거 다른 쿼리와 쿼리 그런

UNION, 그러나 이것은 당신이에서 얻을 것 colmuns를 대체 할 수있는 쿼리 1의 이전 조인 조건에 실패한 모든 행을 가져옵니다

NOT EXISTS(SELECT 1 FROM MISSING_ROWS_TABLE WHERE MAIN_TABLE.JOIN_CONDITION = MISSING_ROWS_TABLE.JOIN_CONDITION) 

있다 MISSING_ROWS_TABLE에 NULL이 있습니다. 외부 조인을 지원하지 않는 코딩 프레임 워크를 사용하여이 작업을 한 번 수행해야했습니다. 재귀 CTE는 하위 쿼리를 허용하지 않으므로 첫 번째 솔루션을 사용해야합니다.

+0

무한 재귀 루프를 얻는 이유를 알아 내는데 시간이 걸렸지 만 얻었습니다. 고마워, 절대 혼자서 알아 내지 못했을거야. – Shelby115