2009-12-07 7 views
3

Django 1.1을 사용하면 어떻게 ORM을 사용하여 크로스 탭 (피벗 테이블) SQL 쿼리를 만들 수 있습니까? 업데이트]어떻게 Django ORM으로 크로스 탭 SQL 쿼리를 만들 수 있습니까?

: 그래서 같은

class Store(models.Model): 
    name = models.CharField(max_length=255) 
    ... 

class Order(models.Model): 
    store = models.ForeignKey(Store, blank=True, null=True, related_name='orders') 
    description = models.CharField(_('Description'), max_length=255) 
    quantity = models.IntegerField(blank=True, null=True)  
    type_detail = models.CharField(_('Type Detail'), max_length=255) 
    slug = models.SlugField(blank=True) 
    cost = models.DecimalField(_("Cost"), max_digits=14, decimal_places=2) 
    modified = models.DateTimeField(_('modified'), auto_now=True) 

현재 뷰가 표시되고 데이터 : 내가 지금 같은 데이터를 보려면이 피벗 할

Store | Type Detail | Quantity 
---------------------------------- 
Walmart | Floor polish | 2   
Walmart | Tiles  | 1   
Walmart | Milk   | 4  
Another | Floor polish | 2   
Another | Tiles  | 1   
Another | Milk   | 4   

이들은 모델 및 출력 요구 사항입니다 :

상점에 대해 수량을 알아야합니다. 수량을 알아야합니다.

Store | Floor polish | Tiles | Milk 
------------------------------------------------ 
Walmart | 2    | 1  | 4 
Another | 2    | 1  | 4 

내가 원하는 것을 설명하기를 바랍니다. 모든 상점이 같은 경우

{% regroup line_items by store.name as store_items %} 
{% for store in store_items %}  
    <tr> 
    <td>{{ store.grouper }}</td> 
    {% for item in store.list %} 
     <td>{{ item.count }}</td> 
    {% endfor %} 
    </tr> 
{% endfor %} 

이 작동합니다 :

당신은 다음과 같이 템플릿에서이 작업을 수행 할 수 있습니다
+1

좀 더 자세하게 설명해야합니다. 어떤 모델을 가지고 있으며 어떤 결과를 성취하고 싶습니까? –

+0

모델 세부 정보로 업데이트했습니다. –

답변

3

(당신이 당신의 템플릿에 line_items를 전달하는 가정도 store.name 가정은 고유 재산) 재고, 그렇지 않으면 당신은 (예를 들어, 재고 항목을 누락 0의 반환) 뷰의 격차를 채우기 위해 필요합니다

-1

장고에 대해 알고 있지만, 여기에 일반 SQL의 안

SELECT Store, 
SUM(CASE WHEN Type_Detail = 'Floor polish' THEN Quantity ELSE 0 END) as 'Floor polish', 
SUM(CASE WHEN Type_Detail = 'Tiles' THEN Quantity ELSE 0 END) as 'Tiles', 
SUM(CASE WHEN Type_Detail = 'Milk' THEN Quantity ELSE 0 END) as 'Milk' 
FROM Order 
GROUP BY Store 
+0

이 방법의 문제점은 열을 SQL에 하드 코딩했기 때문에 새로운 유형이 추가되면 SQL을 변경해야한다는 것입니다. –

2

적절한 크로스 탭에는 각 차원 멤버에 값이 필요합니다. 여기에 내가 만든 것 (아래 참조)이 있습니다. 당신은 doctext 예제에서와 같이 장고 템플릿에서 이것을 사용할 수 있습니다. 따라서 1) 모든 Store 값, 2) 모든 type_detail 값 및 3) store 및 type_detail에 대한 쿼리를 실행합니다. 세 번째 쿼리의 결과는 (store, type) => quantity의 사전으로 들어갑니다.

class Cube(object): 
    """Iterable sparse cube. Iterating gives an item for every dimension member. 

    >>> pythons = ['eric', 'john', 'terry'] 
    >>> cheeses = ['limburg', 'feta', 'parmigiano'] 
    >>> cheese_consumption = { 
     ('eric', 'limburg'): 2, 
     ('eric', 'parmigiano'): 4, 
     ('john', 'feta'): 5 
    } 
    >>> cheese_cube = Cube((pythons, cheeses), cheese_consumption) 
    >>> for python, python_cheeses in cheese_cube: 
     for cheese, consumption in python_cheeses: 
      print python, cheese, consumption or 0 

    eric limburg 2 
    eric feta 0 
    eric parmigiano 4 
    john limburg 0 
    john feta 5 
    john parmigiano 0 
    terry limburg 0 
    terry feta 0 
    terry parmigiano 0 
    """ 
    def __init__(self, dimensions, facts, slice=None): 
     self.dimensions = dimensions 
     self.data_dict = facts 
     self.slice = slice or() 
    def __iter__(self): 
     if len(self.slice) + 1 < len(self.dimensions): 
      for item in self.dimensions[len(self.slice)]: 
       yield item, Cube(self.dimensions, self.data_dict, self.slice + (item,)) 
     else: 
      for item in self.dimensions[len(self.slice)]: 
       yield item, self.data_dict.get(self.slice + (item,), None) 
관련 문제