sql - 如何计算查询集中对的频率
问题描述
我在 Django 中有两个模型:
class Pair(models.Model):
pass
class Person(models.Model):
pair = models.ForeignKey(to=Pair, related_name='mates')
city = models.ForeignKey(to=City)
所以我需要计算来自不同城市的配对频率:
city_a<->city_b: 100
city_a<->city_a: 80
city_b<->city_c: 200
...
对于每个人,我可以通过:
person.pair.mates.exclude(id=person.id).first()
或类似的方式获得另一个人的城市,所以理论上我可以遍历所有实例,Person
然后计算频率,但显然这将是非常低效的。
但我不知道如何通过标准查询集获取这些信息(如果有办法的话)。欢迎任何提示
解决方案
您可以注释这些对,例如:
from django.db.models import Count, F, Q
Person.objects.filter(
Q(pair__mates__lt=F('pk')) | Q(pair__mates__gt=F('pk'))
).values(
city1=F('city__name'),
city2=F('pair__mates__city__name')
).annotate(
number=Count('pk')
).order_by('city1', 'city2')
__name
应该是您要使用的城市的字段。例如__pk
,也可能是一个选项。
查询的工作方式如下:Q(pair__mates__lt=F('pk')) | Q(pair__mates__gt=F('pk'))
通常应该排除引用相同的“伙伴” Person
。然后我们使用从城市.values(..)
中获取name
(或其他文件),并从pair__mates__city__names
. 现在我们有了这两个值,我们Count(..)
得到每组的记录数city1
和city2
。有.order_by(..)
必要避免这种下标,就像从原始查询中qs[1]
返回一条记录一样。Person
因此,查询如下所示:
SELECT app_name_city.name AS city1,
T5.name AS city2,
COUNT(app_name_person.id) AS number
FROM app_name_person
INNER JOIN app_name_pair ON app_name_person.pair_id = app_name_pair.id
INNER JOIN app_name_person T3 ON app_name_pair.id = T3.pair_id
INNER JOIN app_name_city ON app_name_person.city_id = app_name_city.id
INNER JOIN app_name_city T5 ON T3.city_id = T5.id
WHERE T3.id < app_name_person.id OR T3.id > app_name_person.id
GROUP BY app_name_city.name, T5.name
ORDER BY city1 ASC, city2 ASC
这将返回一个QuerySet
字典:
<QuerySet [
{'city1': 'city_a', 'city2': 'city_a', 'number': 80},
{'city1': 'city_a', 'city2': 'city_b', 'number': 100},
{'city1': 'city_b', 'city2': 'city_c', 'number': 200}
]>
推荐阅读
- r - R - 如何将输出(NL API 翻译)作为现有 Tibble 中的新列添加?
- r - 无法访问存储在向量 R 中的 setRefClass 对象的属性
- typescript - 为什么通用告诉我属性不存在
- vue.js - NuxtJS 与使用 VueJS 的 ant design pro 布局
- python - 在 python 中使用带有 a+ 模式的 open 函数的奇怪结果
- php - 如何仅减慢当前请求的速度?sleep() 没有按预期工作
- ios - Swift 5 - 用户第二次单击标签栏按钮后,需要帮助在视图控制器 1 上重新加载 Web 视图
- sql - Oracle xmlagg 字符串缓冲区太小
- javascript - [Vue 警告]:属性或方法“列表”未在实例上定义,但在渲染期间被引用。确保此属性是反应性的 [...]
- elasticsearch - 在 Logstash if 语句中使用非白名单字段