按事件排序查询集

时间:2014-06-19 11:31:39

标签: mysql django

我有一个django模型:

class Field:

choice = models.CharField(choices=choices)

value = models.CharField(max_length=255)  

在我的数据库中,我有一些情况,其中有3个"字段"有相同的选择,有些情况下有1个选择领域

我如何订购查询集以使其返回,按选择排序,但是在开始时将所有的一组放在一组3中?

例如

[1,1,1,3,3,3,4,4,4,2,5]哪里有1,2,3,4,5可能的选择?

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

你应该创建一个函数并检测哪个重复以选择唯一,然后从mysql调用作为函数而不是mysql

答案 1 :(得分:0)

这是我用django的ORM做的最好的事情。基本上,就像在SQL中一样,您必须构造一个自定义的order_by语句。在我们的例子中,我们将place it in the SELECT and then order by it

1)获取按频率排序的选项列表:[1, 3, 4, 2, 5]

freq_list = (
    Field.objects.values_list('choice', flat=True)
    .annotate(c=Count('id')).order_by('-c', 'choice')
)

2)使用枚举:[(0,1), (1,3), (2,4), (3,2), (4,5)]

添加索引
enum_list = list(enumerate(freq_list))

3)创建案例列表:['CASE', 'WHEN choice=1 THEN 0', ..., 'END']

case_list = ['CASE']
case_list += ["WHEN choice={1} THEN {0}".format(*tup) for tup in enum_list]
case_list += ['END']

4)将案例列表合并为一个字符串:'CASE WHEN choice=1 THEN 0 ...'

case_statement = ' '.join(case_list)

5)最后,使用case语句选择一个额外的字段'o',它将是相应的顺序,然后按此字段排序

Field.objects.extra(select={'o': case_statement}).order_by('o')

要简化所有这些,您可以将上述代码放入Model Manager

class FieldManager(models.Manager):
    def get_query_set(self):
        freq_list = (
            Field.objects.values_list('choice', flat=True)
            .annotate(c=Count('id')).order_by('-c', 'choice')
        )
        enum_list = list(enumerate(freq_list))
        case_list = ['CASE']
        case_list += ["WHEN choice={1} THEN {0}".format(*tup) for tup in enum_list]
        case_list += ['END']
        case_statement = ' '.join(case_list)
        ordered = Field.objects.extra(select={'o': case_statement}).order_by('o')
        return ordered

class Field(models.Model):
    ...
    freq_sorted = FieldManager()

现在您可以查询:

Field.freq_sorted.all()

Field

的频率排序QuerySet choices