我有一个类Marketorders,其中包含有关单个市场订单的信息,它们收集在市场快照中(由类Snapshot表示)。每个订单都可以出现在多个快照中,其中最新一行当然是相关的。
class Marketorders(models.Model):
id = models.AutoField(primary_key=True)
snapid = models.IntegerField()
orderid = models.IntegerField()
reportedtime = models.DateTimeField(null=True, blank=True)
...
class Snapshot(models.Model):
id = models.IntegerField(primary_key=True)
...
我正在做的是在多个快照中获取所有订单以进行处理,但我想只包含每个订单的最新行。在SQL中我只会这样做:
SELECT m1.* FROM marketorders m1 WHERE reportedtime = (SELECT max(reportedtime)
FROM marketorders m2 WHERE m2.orderid=m1.orderid);
或更好的联接:
SELECT m1.* FROM marketorders m1 LEFT JOIN marketorders m2 ON
m1.orderid=m2.orderid AND m1.reportedtime < m2.reportedtime
WHERE m2.orderid IS NULL;
然而,我无法弄清楚如何使用Django ORM来做到这一点。有没有原始SQL可以实现这个目的吗?
编辑:只是为了澄清问题。假设我们有以下市场营销人员(遗漏一切不重要且仅使用orderid,报告时间):
1, 09:00:00
1, 10:00:00
1, 12:00:00
2, 09:00:00
2, 10:00:00
如何使用ORM获得以下设置?
1, 12:00:00
2, 10:00:00
答案 0 :(得分:2)
如果我理解正确,您需要一个Marketorder对象列表,其中包含每个orderid报告时间最长的每个Marketorder
这样的事情应该有效(免责声明:没有直接测试):
m_orders = Marketorders.objects.filter(id__in=(
Marketorders.objects
.values('orderid')
.annotate(Max('reportedtime'))
.values_list('id', flat=True)
))
进行文件检查:
http://docs.djangoproject.com/en/dev/topics/db/aggregation/
编辑: 这应该是一个具有特定订单的报告时间最长的单一Marketorder
order = (
Marketorders.objects
.filter(orderid=the_orderid)
.filter(reportedtime=(
Marketorders.objects
.filter(orderid=the_orderid)
.aggregate(Max('reportedtime'))
['reportedtime__max']
))
)
答案 1 :(得分:0)
你有充分的理由不使用ForeignKey或(在你的情况下更好)ManyToManyField。这些字段代表ur模型的关系结构。
此外,没有必要声明pk-field id。如果没有定义pk,django会添加id。
下面的代码允许像这样的orm-queries:
m1 = Marketorder()
m1.save() # important: primary key will be added in db
s1 = Snapshot()
s2 = Snapshot()
s1.save()
s2.save()
m1.snapshots.add(s1)
m1.snapshots.add(s2)
m1.snapshots.all()
m1.snapshots.order_by("id") # snapshots in relations with m1
# ordered by id, that is added automatically
s1.marketorder_set.all() # reverse
以便查询:
snapshot = Snapshot.objects.order_by('-id')[0] # order desc, pick first
marketorders = snapshot.marketorder_set.all() # all marketorders in snapshot
或压缩:
marketorders = Snapshot.objects.order_by('-id')[0].marketorder_set.all()
models.py :
class Snapshot(models.Model):
name = models.CharField(max_length=100)
class Marketorder(models.Model):
snapshots = models.ManyToManyField(Snapshot)
reportedtime = models.DateTimeField(auto_now= True)
按照惯例,所有模型类名称都是单数。 Django自动在不同的地方复数。