按2个字段分组,然后按每个组的总和排序,多个注释为django

时间:2018-07-26 06:22:29

标签: mysql django django-models django-queryset

我试图按发票的总保证金总和来订购顶级产品,如下所示:

  • 按给定的store_id过滤发票
  • product_name分组
  • 然后获取每个组的Sum中的gross_margin
  • 最后按Sum中的gross_margin(从高到低)对其排序

以前的代码错误:

high_margin = StoreInvoiceBreakup.objects \
  .filter(store_invoice__store_id=store_id) \   
  .annotate(product_count=Count('product_name')) \
  .annotate(gross_margin_sum=Sum('gross_margin')) \
  .order_by('-gross_margin_sum') \
  .values(name=F('product_name')) \
  .distinct()[:int(top_count)]

然后通过Stack Overflow similar question通过以下方式解决了多个批注问题:
(因为先前的代码给出了错误的结果。)

正确的新代码:

high_margin = StoreInvoiceBreakup.objects \
  .filter(store_invoice__store_id=store_id) \
  .values('product_name') \
  .annotate(gross_margin_sum=Sum('gross_margin')) \
  .order_by('gross_margin_sum') \
  .distinct()[:int(sell_range)]

输出看起来像:

"high_margin ": [{
  "product_name": "ABCD",
  "gross_margin_sum": 100  --sum of all margins for abcd
}...other products with sum]

哪个绝对是correct,但是遇到了另一个问题,例如:
商店可以具有相同的product_name产品,但是有效期可能不同。
所以我想要的是

  • 按产品product_nameexpiry_date对产品进行分组 组合。
  • 然后获取每个组的margin和,并按Sum的顺序返回,其中 不同的组合。 (不仅限于不同的产品名称。)

*删除不同内容没有帮助

或者通过cursor进行 MySQL 查询也会很有帮助。如果无法通过docs的queryset来实现。
发票分类数据如下:

  name  | margin  | ... | total | tax | etc..
  abcd  | 50      | ... |
  abcd  | 50      | ... |
  abcd  | 15      | ... |
  abcd  | 15      | ... |

输出应为:

"high_margin ": [{
  "product_name": "ABCD",
  "gross_margin_sum": 100  --sum for 2018 and abcd
  "expiry_date": 2018
},
{
  "product_name": "ABCD",
  "gross_margin_sum": 30  --sum for 2017 and abcd
  "expiry_date": 2017
},... other products with sum and expiry_date]

StoreProducts 如下:

  name  |  expiry_date  | size | price | etc...
  abcd  |  2018         |
  abcd  |  2017         |
  xyz   |  2019         |
  pqrs  |  2017         |
  • 保证金仅存在于发票中,而不存在于商店产品中。
  • 有效日期仅存在于商店产品中,不存在于发票中
  • 我还希望能够更改最终输出名称。
  • Invoice_product通过foreign_key映射到store_product_mapping, 然后将其映射到master_product

也许SQL查询看起来像:

SELECT NAME, EXPIRY_DATE, SUM(GROSS_MARGIN)
FROM INVOICE_BREAKUP GROUP BY NAME, EXPIRY_DATE
WHERE STORE_ID = 1

Flow *不是实际流量

1 个答案:

答案 0 :(得分:0)

print(str(high_margin.query))

通过这种方式,您可以获取queryset产生的内容,并像answer here.所说的那样进行延迟查询 因此,我通过在expiry_date中添加values来获得预期的SQL查询,该查询将按名称分组,并按docs所述的到期日期进行分组。
代码更改为:

high_margin = StoreInvoiceBreakup.objects \
  .filter(store_invoice__store_id=store_id) \
  .values('product_name', 'expiry_date') \
  .annotate(gross_margin_sum=Sum('gross_margin')) \
  .order_by('gross_margin_sum') \
  .distinct()[:int(sell_range)]

*不确定是否正确

相关问题