django에서 GROUP BY로 쿼리하는 방법
모델을 문의합니다.
Members.objects.all()
그러면 다음과 같이 반환됩니다.
Eric, Salesman, X-Shop
Freddie, Manager, X2-Shop
Teddy, Salesman, X2-Shop
Sean, Manager, X2-Shop
이다.group_by
다음과 같이 데이터베이스에 쿼리합니다.
Members.objects.all().group_by('designation')
물론 효과가 없겠죠.우리가 속임수를 쓸 수 있다는 걸 알아django/db/models/query.py
패치를 적용하지 않고 실행하는 방법을 알고 싶을 뿐입니다.
집약을 실시하는 경우는, ORM 의 집약 기능을 사용할 수 있습니다.
from django.db.models import Count
result = (Members.objects
.values('designation')
.annotate(dcount=Count('designation'))
.order_by()
)
그 결과 다음과 같은 쿼리가 생성됩니다.
SELECT designation, COUNT(designation) AS dcount
FROM members GROUP BY designation
그리고 출력은 다음과 같은 형태가 될 것입니다.
[{'designation': 'Salesman', 'dcount': 2},
{'designation': 'Manager', 'dcount': 2}]
」를 하지 않는 는,order_by()
기본 정렬이 예상과 다를 경우 잘못된 결과가 나타날 수 있습니다.
합니다.values
예를 들어 다음과 같습니다.
.values('designation', 'first_name', 'last_name')
참고 자료:
- 장고 매뉴얼: , 및
- 장고 문서:집약, 특히 디폴트 오더와의 상호 작용 또는
간단한 해결 방법이지만 적절한 방법은 아닌 원시 SQL을 사용하는 것입니다.
results = Members.objects.raw('SELECT * FROM myapp_members GROUP BY designation')
하나의 은 '보다 낫다'를 입니다.group_by
★★★★
query = Members.objects.all().query
query.group_by = ['designation']
results = QuerySet(query=query, model=Members)
이제 결과 변수를 반복하여 결과를 검색할 수 있습니다.:group_by
는 문서화되어 있지 않으며 향후 버전의 Django에서 변경될 수 있습니다.
왜 ★★★★★★★★★★★★★★★★★★★★★★★. 왜런이 이? ???group_by
order_by
★★★★★★★★★★★★★★★★★★★★★★★★★★★
이 경우에도 하실 수 있습니다.regroup
by.template template tag © ★★★★★★★★★★★★★★★★★★:
cities = [
{'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
{'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
{'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
{'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
{'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]
...
{% regroup cities by country as countries_list %}
<ul>
{% for country in countries_list %}
<li>{{ country.grouper }}
<ul>
{% for city in country.list %}
<li>{{ city.name }}: {{ city.population }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
다음과 같습니다.
- 인도
- 뭄바이: 1,900,000
- 캘커타: 15,000,000
- 미국
- 뉴욕: 2,000,000
- 시카고: 700,000
- ★★★★★★ 。
- 도쿄: 3300,000
,에서도합니다.QuerySet
나는 믿는다
출처 : https://docs.djangoproject.com/en/2.1/ref/templates/builtins/ #재그룹화
: " " : " 에 .regroup
태그는 사전 목록이 키 수집되지 않은 경우 예상대로 작동하지 않습니다.그것은 반복적으로 작동한다.따라서 목록(또는 쿼리 세트)을 라우터의 키에 따라 정렬한 후regroup
붙이다
Django는 쿼리에 의한 자유 그룹을 지원하지 않습니다.나는 그것을 아주 나쁜 방법으로 배웠다.ORM은 커스텀 SQL을 사용하지 않고 원하는 작업을 지원하도록 설계되지 않았습니다.제한은 다음과 같습니다.
- RAW sql(MyModel.objects.raw() 등)
cr.execute
문장(및 결과의 수작업 구문 분석)..annotate()
('lines_count=Count('lines')'는 .contate를 말합니다).
을 qs
해서 '어느끼다'라고 불러도 요.qs.query.group_by = ['field1', 'field2', ...]
그러나 편집 중인 쿼리가 불분명하고 QuerySet 객체의 내부가 파손되지 않는다는 보장이 없는 경우에는 위험합니다.또한 내부(문서화되어 있지 않은) API로 향후 Django 버전과 호환되지 않을 수 있습니다.
이 내장되어 있는 것도 할 수 .itertools.groupby
★★★★
from itertools import groupby
designation_key_func = lambda member: member.designation
queryset = Members.objects.all().select_related("designation")
for designation, member_group in groupby(queryset, designation_key_func):
print(f"{designation} : {list(member_group)}")
원시 SQL, 서브쿼리, 서드파티 립스, 템플태그 등은 필요 없습니다.또한 제 눈에는 비단어적이고 명료합니다.
다음 모듈에서는 Django 모델을 그룹화하고 결과에서 QuerySet을 사용할 수 있습니다.https://github.com/kako-nawao/django-group-by
예를 들어 다음과 같습니다.
from django_group_by import GroupByMixin
class BookQuerySet(QuerySet, GroupByMixin):
pass
class Book(Model):
title = TextField(...)
author = ForeignKey(User, ...)
shop = ForeignKey(Shop, ...)
price = DecimalField(...)
class GroupedBookListView(PaginationMixin, ListView):
template_name = 'book/books.html'
model = Book
paginate_by = 100
def get_queryset(self):
return Book.objects.group_by('title', 'author').annotate(
shop_count=Count('shop'), price_avg=Avg('price')).order_by(
'name', 'author').distinct()
def get_context_data(self, **kwargs):
return super().get_context_data(total_count=self.get_queryset().count(), **kwargs)
'book/books.books.'
<ul>
{% for book in object_list %}
<li>
<h2>{{ book.title }}</td>
<p>{{ book.author.last_name }}, {{ book.author.first_name }}</p>
<p>{{ book.shop_count }}</p>
<p>{{ book.price_avg }}</p>
</li>
{% endfor %}
</ul>
「 」와의 annotate
/aggregate
는 관련 장고 쿼리)을입니다.book.author.last_name
.
그룹화된 인스턴스의 PK가 필요한 경우 다음 주석을 추가합니다.
.annotate(pks=ArrayAgg('id'))
의:ArrayAgg
는 Postgres 고유의 기능으로, Django 1.9 이후부터 사용할 수 있습니다.https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/aggregates/ #arrayagg
매뉴얼에는 값을 사용하여 쿼리셋을 그룹화할 수 있다고 기재되어 있습니다.
class Travel(models.Model):
interest = models.ForeignKey(Interest)
user = models.ForeignKey(User)
time = models.DateTimeField(auto_now_add=True)
# Find the travel and group by the interest:
>>> Travel.objects.values('interest').annotate(Count('user'))
<QuerySet [{'interest': 5, 'user__count': 2}, {'interest': 6, 'user__count': 1}]>
# the interest(id=5) had been visited for 2 times,
# and the interest(id=6) had only been visited for 1 time.
>>> Travel.objects.values('interest').annotate(Count('user', distinct=True))
<QuerySet [{'interest': 5, 'user__count': 1}, {'interest': 6, 'user__count': 1}]>
# the interest(id=5) had been visited by only one person (but this person had
# visited the interest for 2 times
다음 코드를 사용하여 모든 책을 찾고 이름별로 그룹화할 수 있습니다.
Book.objects.values('name').annotate(Count('id')).order_by() # ensure you add the order_by()
여기서 치트페이퍼를 보실 수 있습니다.
이 스니펫의 예시와 같이 커스텀 SQL을 실행해야 합니다.
또는 온라인 Django 문서에 나와 있는 커스텀 매니저의 경우:
이것은 조금 복잡하지만, 질문자가 단 한 번의 DB 히트만으로 무엇을 예상했는지 확인해 보십시오.
from django.db.models import Subquery, OuterRef
member_qs = Members.objects.filter(
pk__in = Members.objects.values('designation').distinct().annotate(
pk = Subquery(
Members.objects.filter(
designation= OuterRef("designation")
)
.order_by("pk") # you can set other column, e.g. -pk, create_date...
.values("pk")[:1]
)
)
.values_list("pk", flat=True)
)
즉, 일부 필드를 기반으로 "복제 제거"를 수행해야 하는 경우 또는 ORM 개체를 그대로 쿼리해야 하는 경우 다음과 같은 해결 방법을 생각해냈습니다.
from django.db.models import OuterRef, Exists
qs = Members.objects.all()
qs = qs.annotate(is_duplicate=Exists(
Members.objects.filter(
id__lt=OuterRef('id'),
designation=OuterRef('designation')))
qs = qs.filter(is_duplicate=False)
'을 붙이는 예요.is_duplicate
편리한 필터링(모델과 요건에 따라 다를 수 있음)을 사용한 다음 해당 필드를 사용하여 중복을 필터링하는 것만으로 값을 매길 수 있습니다.
플레인 값이나 사전뿐만 아니라 모델 객체를 원하는 경우 다음과 같은 작업을 수행할 수 있습니다.
members = Member.objects.filter(foobar=True)
designations = Designation.objects.filter(member__in=members).order_by('pk').distinct()
member__in
에 「」가 붙습니다.__in
이 「 」인 Car
하다, 사용하다car__in
.
어떤 이유에서, 위에 언급된 솔루션 나를 위해 일하지 않았다.이것이 노력했습니다:
dupes_query = MyModel.objects.all().values('my_field').annotate(
count=Count('id')
).order_by('-count').filter(count__gt=1)
나는 그것이 도움이 되길 바랍니다.
from django.db.models import Sum
Members.objects.annotate(total=Sum(designation))
첫째, 당신은 그때 Sum 가져올 수 없습니다. 필요가 있다.
언급URL:https://stackoverflow.com/questions/629551/how-to-query-as-group-by-in-django
'source' 카테고리의 다른 글
테이블의 기본 키를 리셋하려면 어떻게 해야 합니까? (0) | 2022.09.08 |
---|---|
tail과 유사한 파일의 마지막 n 행을 가져옵니다. (0) | 2022.09.08 |
HTML 파일을 PDF로 변환 (0) | 2022.09.08 |
왜 사람들은 json 응답 앞에 "1; " 및 "for(;;)"와 같은 코드를 넣을까요? (0) | 2022.09.08 |
Mariadb 연결 클라이언트:mysql 8.0에서 사용자(암호: NO 사용)에 대한 액세스가 거부되었습니다. (0) | 2022.09.08 |