All*_*Liu 15 mysql django group-concat
说我有下面的表格fruits:
id | type | name
-----------------
0 | apple | fuji
1 | apple | mac
2 | orange | navel
Run Code Online (Sandbox Code Playgroud)
我的目标是最终得到一个不同types的逗号和逗号分隔的列表names:
apple, 2, "fuji,mac"
orange, 1, "navel"
Run Code Online (Sandbox Code Playgroud)
这可以GROUP_CONCAT在MySQL中轻松完成,但我遇到了与Django等效的问题.这是我到目前为止,但我错过了GROUP_CONCAT这些东西:
query_set = Fruits.objects.values('type').annotate(count=Count('type')).order_by('-count')
Run Code Online (Sandbox Code Playgroud)
我想尽可能避免使用原始SQL查询.
任何帮助将不胜感激!
谢谢!=)
Sha*_*gla 36
您可以创建自己的聚合函数(doc)
from django.db.models import Aggregate
class Concat(Aggregate):
function = 'GROUP_CONCAT'
template = '%(function)s(%(distinct)s%(expressions)s)'
def __init__(self, expression, distinct=False, **extra):
super(Concat, self).__init__(
expression,
distinct='DISTINCT ' if distinct else '',
output_field=CharField(),
**extra)
Run Code Online (Sandbox Code Playgroud)
并简单地用作:
query_set = Fruits.objects.values('type').annotate(count=Count('type'),
name = Concat('name')).order_by('-count')
Run Code Online (Sandbox Code Playgroud)
我使用的是django 1.8和mysql 4.0.3
使用我维护GroupConcat的 Django-MySQL 包 (
https://django-mysql.readthedocs.org/en/latest/aggregates.html#django_mysql.models.GroupConcat )。有了它,你可以简单地做到:
>>> from django_mysql.models import GroupConcat
>>> Fruits.objects.annotate(
... count=Count('type'),
... name_list=GroupConcat('name'),
... ).order_by('-count').values('type', 'count', 'name_list')
[{'type': 'apple', 'count': 2, 'name_list': 'fuji,mac'},
{'type': 'orange', 'count': 1, 'name_list': 'navel'}]
Run Code Online (Sandbox Code Playgroud)
注意Django(> = 1.8)提供Database functions支持.
https://docs.djangoproject.com/en/dev/ref/models/database-functions/#concat
这是一个增强版 Shashank Singla
from django.db.models import Aggregate, CharField
class GroupConcat(Aggregate):
function = 'GROUP_CONCAT'
template = '%(function)s(%(distinct)s%(expressions)s%(ordering)s%(separator)s)'
def __init__(self, expression, distinct=False, ordering=None, separator=',', **extra):
super(GroupConcat, self).__init__(
expression,
distinct='DISTINCT ' if distinct else '',
ordering=' ORDER BY %s' % ordering if ordering is not None else '',
separator=' SEPARATOR "%s"' % separator,
output_field=CharField(),
**extra
)
Run Code Online (Sandbox Code Playgroud)
用法:
LogModel.objects.values('level', 'info').annotate(
count=Count(1), time=GroupConcat('time', ordering='time DESC', separator=' | ')
).order_by('-time', '-count')
Run Code Online (Sandbox Code Playgroud)
Django ORM 不支持这一点;如果你不想使用原始 SQL 那么你需要group 和 join。
| 归档时间: |
|
| 查看次数: |
8529 次 |
| 最近记录: |