2009-12-07 107 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 

我希望能解釋我需要什麼。

+1

您將不得不提供更多的細節。你有什麼樣的模型,你想達到什麼樣的結果? – 2009-12-07 10:08:10

+0

我使用模型詳細信息更新 – 2009-12-07 10:28:24

回答

3

爲此,您可以在模板如下(假設你傳遞line_items到您的模板,並假設store.name是一個獨特的屬性):

{% 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 %} 

如果所有的商店具有相同的該會工作庫存,否則你將需要填補國內空白的視圖(返回0的遺漏庫存物品,例如)

-1

不知道Django的,但在這裏是普通的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。 – 2012-06-01 12:40:35

2

適當的交叉表需要每個維度成員的值。這是我編造的東西(見下文)。您可以像在doctext示例中一樣在Django模板中使用它。因此,您將針對1)所有商店值,2)所有type_detail值以及3)每個商店和type_detail的數量發出查詢。然後將第三個查詢的結果寫入(store,type)=>數量的字典中。

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)