2011-05-09 4 views
7

누구나 order_by()을 입력하면 INNER JOIN에서 LEFT OUTER JOIN으로 출력이 변경되는 쿼리를 추가 할 수 있습니다.Django order_by가 LEFT JOIN을 야기 함

INNER JOIN을 보존 할 수있는 방법이 있습니까?

data = models.RetailSalesFact.objects.values('customer_key__customer_state', 
              'date_key__calendar_month_name') 
data = data.filter(date_key__calendar_year=year) 
data = data.annotate(sales=Sum('sales_quantity')) 
data = data.order_by('date_key__calendar_month_name') 

전 :

SELECT Customer_Dimension.Customer_State, Date_Dimension.Calendar_Month_Name, 
     SUM(Retail_Sales_Fact.Sales_Quantity) AS sales 
    FROM Retail_Sales_Fact 
    INNER JOIN Customer_Dimension 
     ON (Retail_Sales_Fact.Customer_Key = Customer_Dimension.Customer_Key) 
    INNER JOIN Date_Dimension 
     ON (Retail_Sales_Fact.Date_Key = Date_Dimension.Date_Key) 
    WHERE Date_Dimension.Calendar_Year = ? 
    GROUP BY Customer_Dimension.Customer_State, 
      Date_Dimension.Calendar_Month_Name 
    ORDER BY Date_Dimension.Calendar_Month_Name ASC 

후 :

SELECT Customer_Dimension.Customer_State, Date_Dimension.Calendar_Month_Name, 
     SUM(Retail_Sales_Fact.Sales_Quantity) AS sales 
    FROM Retail_Sales_Fact 
    INNER JOIN Customer_Dimension 
     ON (Retail_Sales_Fact.Customer_Key = Customer_Dimension.Customer_Key) 
    LEFT OUTER JOIN Date_Dimension 
     ON (Retail_Sales_Fact.Date_Key = Date_Dimension.Date_Key) 
    WHERE Date_Dimension.Calendar_Year = ? 
    GROUP BY Customer_Dimension.Customer_State, 
      Date_Dimension.Calendar_Month_Name 
    ORDER BY Date_Dimension.Calendar_Month_Name ASC 
+0

대답은 업데이트 ... – FallenAngel

답변

1

나는 INNER JOIN 's의 경우는 말할 수 없기 때문에 ORM이 LEFT JOIN을하고 추측에는 요 여기서 제한은 주문 조항보다 다소 제한적입니다. 매치가 맞는지 여부에 관계없이 모든 레코드를 주문해야한다고 생각하기 때문입니다.

INNER JOINRaw SQL을 사용하여 강제로 사용할 수 있습니다. 또는 filter 앞에 order_by을 적용하여 ORM을 속일 수 있습니까?

1

당신은 외부 테이블 (date_dimension__calendar_year = 년)에 필터를 옮기고, 그래서 당신은 내부 조인 사용하거나 왼쪽 외부 조인 여부, 결과 집합 사이에 차이가있을 수 없습니다.

주문 결과는 중간 결과 집합에서 처리됩니다. 내부 조인 된 테이블에서 수행 된 경우 테이블이 결합 된 후에 완료되어야합니다. 두 읽기 : 결합 된 레코드를 주문하십시오.

외부 조인 된 테이블 (이 경우 요청하는 것)에서만 주문을 완료하면 쿼리 최적화 프로그램에서 전체 집합을 두 번 읽는 것을 피할 수 있습니다. 대신 외부 테이블을 두 번만 읽습니다. 옵티마이 저가 처리 능력면에서 이점을 절감 할 수 있습니다.

그것은 단지 추측입니다. 결과 세트는 어느 쪽이든 똑같이 나타납니다. 나는 두 가지 방법으로 시간을 할애 할 수 있는지, 그리고 어느 것이 더 오래 걸리는지 궁금해.

+1

결과 집합은 동일하지만 내부 사이의 시간은 가입과 LEFT 조인은 매우 중요하다. 상대적으로 작은 데이터 세트에서는 아무 것도 해치울 수 없지만 테이블이 가득 차면 큰 영향을 미칩니다. –

+0

inner-join + order-by은 left-outer-join + order-by보다 시간이 덜 걸립니까? 나는 당신이 원래 내부 조인을 비교하고 있다고 생각했다. (순서없이). – Chains

+0

Group-by 문을 다시 주문하십시오. 귀하의 데이터 세트는 실제로 Group-by에 의해 두 번 정렬되고이어서 Order-by에 의해 두 번 정렬됩니다. GROUP BY Date_Dimension.Calendar_Month_Name, Customer_Dimension.Customer_State를 차례로 변경 한 다음 order-by 절을 제거하면 원하는 결과를 얻을 수 있습니까? – Chains