使用Django 1.1,如何使用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
我希望这能解释我的需要。
答案 0 :(得分: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 :(得分:2)
正确的交叉表需要每个维度成员的值。这是我编造的东西(见下文)。您可以在Django模板中使用它,就像在doctext示例中一样。因此,您将发出1)所有商店值,2)所有type_detail值和3)每个商店的数量和type_detail的查询。然后第三个查询的结果进入(store,type)=&gt;的字典中。量。
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)
答案 2 :(得分:-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