python - 提取月份和年份,然后使用 Django ORM 计数并通过分组获取平均值
问题描述
我想提取年份和月份。然后我想按年、月和地区分组,然后计算行数并计算每个组的平均价格。实际上下面的 SQL 语句做了我想做的事情。那么,我怎样才能用 Django ORM 做到这一点?
SELECT district, month, year, COUNT(ilan_no) , TO_CHAR(AVG(price), '9999999999') as avg_price
FROM (
SELECT
ilan_no,
district,
price,
EXTRACT (MONTH FROM add_date) as month,
EXTRACT (YEAR FROM add_date) as year
FROM ilan) as foo
GROUP BY district, month, year
ORDER BY year, month, district
模型.py:
class Ilan(models.Model):
ilan_no = models.IntegerField(unique=True, blank=True, null=True)
url = models.CharField(unique=True, max_length=255, blank=True, null=True)
add_date= models.DateField()
origin = models.CharField(max_length=100, blank=True, null=True)
city = models.CharField(max_length=20, blank=True, null=True)
district = models.CharField(max_length=30, blank=True, null=True)
price = models.IntegerField(blank=True, null=True)
序列化程序.py:
class IlanSerializer(serializers.ModelSerializer):
class Meta:
model = Ilan
fields = ['ilan_no', 'add_date', 'district', 'price']
我在下面尝试过查询集,但 value() 方法不适用于 Rest-Framework 序列化程序。
视图.py:
class IlcePriceAndSizeDistributionListView(ListAPIView):
queryset = Ilan.objects.annotate(year=ExtractYear('add_date')).annotate(month=ExtractMonth('add_date')).values('district', 'year', 'month', 'ilan_no', 'add_date', 'price').annotate(
ortalama_m2=Avg('m2_net')).annotate(ortalama=Avg('price')).annotate(count=Count('ilan_no')).order_by('year', 'month')
serializer_class = IlanSerializer
解决方案
试试这种方式,让我知道它以后是否有效。
from django.db.models import F, Q, Avg, Subquery, OuterRef, Count, IntegerField
from django.db.models.functions import ExtractMonth, ExtractYear
q = Ilan.objects.annotate(
month=ExtractMonth('add_date'),
year=ExtractYear('add_date')
).values('district','month','year')
qsub = q.filter(
Q(district=OuterRef('district')),
Q(month=OuterRef('month')),
Q(year=OuterRef('year')),
)
qset = q.annotate(count = Subquery(
qsub.annotate(num = Count('year')).values('num'),
output_field = IntegerField)
).annotate(avg_price = Subquery(
qsub.annotate(avg = Avg('price').values('avg'),
output_field = IntegerField)
)
).order_by('year', 'month', 'district')
生成的sql:
SELECT "myapp_ilan"."district",
django_date_extract('month', "myapp_ilan"."add_date") AS "month",
django_date_extract('year', "myapp_ilan"."add_date") AS "year",
(SELECT COUNT(django_date_extract('year', U0."add_date")) AS "num"
FROM "myapp_ilan" U0
WHERE (U0."district" = ("myapp_ilan"."district")
AND django_date_extract('month', U0."add_date") = (django_date_extract('month', "myapp_ilan"."add_date"))
AND django_date_extract('year', U0."add_date") = (django_date_extract('year', "myapp_ilan"."add_date")))
GROUP BY U0."district",
django_date_extract('month', U0."add_date"),
django_date_extract('year', U0."add_date")) AS "count",
(SELECT AVG(U0."price") AS "avg"
FROM "myapp_ilan" U0
WHERE (U0."district" = ("myapp_ilan"."district")
AND django_date_extract('month', U0."add_date") = (django_date_extract('month', "myapp_ilan"."add_date"))
AND django_date_extract('year', U0."add_date") = (django_date_extract('year', "myapp_ilan"."add_date")))
GROUP BY U0."district",
django_date_extract('month', U0."add_date"),
django_date_extract('year', U0."add_date")) AS "avg_price"
FROM "myapp_ilan"
ORDER BY "year" ASC,
"month" ASC,
"myapp_ilan"."district" ASC
推荐阅读
- android - 我的应用(游戏)在安装时在小米手机中被检测为木马,小米手机将我的应用检测为木马
- php - 如何删除第一个数组值PHP
- python - 使用什么代码来交叉引用具有重复值的复杂数据集?
- typescript - 材料 ui 包装器导出接口在打字稿中铸造任何类型(反应)
- sql-server - 来自前端的 DataSync 问题
- c# - 如何使用 C# 将本地文件链接添加到导出的 CSV 文件
- python - 异步传输/协议的文件描述符
- python - 如何从模块调用函数内的函数
- javascript - Q.denodeify 示例未正确执行
- python - 将具有可变长度的多个列表作为参数传递给函数