可以在django中提出这样的请求吗?

时间:2017-08-04 14:42:29

标签: django distinct django-queryset

   name  |   date     | price
----------------------------
product1 | 01.02.2017 | 100
product1 | 03.02.2017 | 200*
product1 | 07.02.2017 | 300*
product2 | 02.02.2017 | 300
product2 | 04.02.2017 | 200*
product2 | 08.02.2017 | 200*

计算两个日期内价格发生变化的产品数量。 例如,回答: 1。,只有produc1(200 => 300),product2(200 = 200)。

3 个答案:

答案 0 :(得分:0)

我不确定您是否可以直接通过ORM获取您想要的内容,但您始终可以自己编写代码。

示例步骤:

  1. 获取第一个日期的产品
  2. 获取第二个日期的产品
  3. 假设产品相同且只有价格在for循环检查中发生变化并比较2个查询集元素的价格并保留一个计数器(如果它们不同)
  4. 不是最好的解决方案,但可以解决一些问题。希望这有帮助!

答案 1 :(得分:0)

基于以上所述:

dates = Request.objects.all().values('date').order_by('-date').distinct()[:2] # last max 2 date

if dates.count() < 2:
    return None

requests = Request.objects.filter(date__in=dates).order_by(
    'product', 'price'
).distinct(
    'product', 'price'
).values('pk')

# can't requests.annotate() because .distinct()
products = Request.objects.filter(pk__in=requests).values('product').annotate(
    count=Count('product')
).filter(count__gt=1).values('product')

if not products.exists():
    return None

# return .all() or .count()

我唯一不喜欢的事情:

.filter(pk__in=requests).

谢谢大家的帮助!

答案 2 :(得分:0)

我能够实施的最佳可行解决方案并不像我希望的那样优雅。

from collections import Counter
from datetime import date
from django.db.models import Count

date_from = date(2017, 2, 3)
date_to = date(2017, 2, 8)   

# this returns the products grouped by price and name.
# where there is more than one row of a product indicates
# a price change
reqs = Request.objects.filter(
        date__gte=date_from, 
        date__lte=date_to
    ).values(
        'product', 
        'price'
    ).annotate(
        count=Count('pk')
    ).order_by(
        'product', 
        'price'
    )

# count the occurrences of each row
counter = Counter(r['product'] for r in reqs)

# counts of two or more have had the price change.
products_price_changed = [p for p in counter if counter[p] > 1]

结果是已更改的产品名称列表。如果您想知道有多少更改了,您可以:

len(products_price_changed)
相关问题