>

다음과 같은 모델이 있습니다 :

class Payment(TimeStampModel):
    timestamp = models.DateTimeField(auto_now_add=True)
    amount = models.FloatField()
    creator = models.ForeignKey(to='Payer')

일일 평균 지출을 계산하는 올바른 방법은 무엇입니까? 나는 하루 단위로 집계 할 수 있지만, 지불 인이 아무것도 지출하지 않는 날은 계산되지 않습니다.

업데이트 :

내 데이터베이스에 3 월 1 일부터 1 월 1 일까지 두 개의 레코드 만 있다고 가정 해 봅시다. 하루 평균 지출은 무엇인가

(Sum of all spendings) / (March 1 - January 1)

60으로 나눈

물론 이것은 물론 항목 당 평균 지출을 제공하며 며칠 동안 나에게 2를 줄 것입니다 :

for p in Payment.objects.all():
    print(p.timestamp, p.amount)
p = Payment.objects.all().dates('timestamp','day').aggregate(Sum('amount'), Avg('amount'))
print(p

출력 :

2019-03-05 17:33:06.490560+00:00 456.0
2019-01-05 17:33:06.476395+00:00 123.0
{'amount__sum': 579.0, 'amount__avg': 289.5}

  • 답변 # 1

    백엔드에 따라 다르지만 금액 합계를 최대 및 최소 타임 스탬프 사이의 일 수 차이로 나누려고합니다. Postgres에서는 단순히 두 날짜를 빼서 둘 사이의 일 수를 얻을 수 있습니다. MySQL에는 DateDiff라는 함수가 있는데 두 개의 날짜가 걸리고 그 사이의 일 수를 반환합니다.

    class Date(Func):
        function = 'DATE'
    class MySQLDateDiff(Func):
        function = 'DATEDIFF'
        def __init__(self, *expressions, **extra):
            expressions = [Date(exp) for exp in expressions]
            extra['output_field'] = extra.get('output_field', IntegerField())
            super().__init__(*expressions, **extra)
    class PgDateDiff(Func):
        template = "%(expressions)s"
        arg_joiner = ' - '
        def __init__(self, *expressions, **extra):
            expressions = [Date(exp) for exp in expressions]
            extra['output_field'] = extra.get('output_field', IntegerField())
            super().__init__(*expressions, **extra)
    agg = {
        avg_spend: ExpressionWrapper(
            Sum('amount') / (PgDateDiff(Max('timestamp'), Min('timestamp')) + Value(1)),
            output_field=DecimalField())
    }
    avg_spend = Payment.objects.aggregate(**agg)
    
    

    물론 나에게 딱 맞는 것 같습니다. 물론 테스트하지는 않았습니다. 물론, 백엔드 인 경우 MySQLDateDiff를 사용하십시오.

  • 답변 # 2

    최소 및 최대 타임 스탬프와 총액을 집계 할 수 있습니다 :

    from django.db.models import Min, Max, Sum
    def average_spending_per_day():
        aggregate = Payment.objects.aggregate(Min('timestamp'), Max('timestamp'), Sum('amount'))
        min_datetime = aggregate.get('timestamp__min')
        if min_datetime is not None:
            min_date = min_datetime.date()
            max_date = aggregate.get('timestamp__max').date()
            total_amount = aggregate.get('amount__sum')
            days = (max_date - min_date).days + 1
            return total_amount / days
        return 0
    
    

    와이즈 비가 있다면  그런 다음 db 테이블에 일부 데이터가 있으며 최대 날짜 및 총 금액도 있습니다. 그렇지 않으면 0 또는 원하는 것을 반환합니다.

    min_datetime

관련 자료

  • 이전 c# - EditorWindow 스크립트에서 EditorGUILayoutToggle을 어떻게 굵게 할 수 있습니까?
  • 다음 간단한 해시 함수 C에 단어를 삽입하는 방법