1


我有一个模型,其data类型JSONField为 from django.contrib.postgres.fields。json结构是这样的:

{'aa': 1, 'bb': 2, 'cc': 4}

我想汇总aacc键的总和 - 所以在这种情况下,它将是 5。另外 - 我不能保证aa或者cc将在 json 中。
这可能吗?如果是这样 - 我想按汇总数据排序。
例子:

  1. id: 1, 数据 = {'aa': 1, 'bb': 2, 'cc':4}
  2. id: 2, 数据 = {'aa': 3, 'bb': 2}
  3. id: 3, 数据 = {'cc': 7}
  4. id: 4, 数据 = {'bb': 7}

我想做一个查询,例如:
MyModel.objects.aggregate(my_sum).order_by(my_sum)
聚合后查询集中的有序行将是:

  1. 编号:3
  2. 编号:1
  3. 编号:2
  4. 编号:4

谢谢!

4

2 回答 2

2

我知道您想为每一行总结一个值和 b 值,然后按总和值对每一行进行排序。正确的?

-> ->>这是如何在 PostgreSQL 中选择 JSON 格式的键或值(我不知道它是否也适用于 MySQL 或其他,我通常使用 PostgreSQL)。这里有很好的资源。您在名为 ' data' 的列中的数据是{"aa":3, "bb":2, "cc":5}. 所以你选择 aa 值data->>'aa'。万一{'classification':{'pc':5000}}呢?您需要选择 pc 值。然后data->'classification'->>'pc'

:: 符号是强制转换操作。

CAST(data->'aa' AS INTEGER)

data->'aa'::int

类 RawSQL(sql, params, output_field=None)

RawSQL("((data->>'aa'::int), (0,)") 并不意味着如果 aa 不存在,它的值为 0。0 是参数。

queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))

好吧,如果你可以像这样修改你的数据

  • id: 1, 数据 = {'aa': 1, 'bb': 2, 'cc':4}
  • id: 2, 数据 = {'aa': 3, 'bb': 2, 'cc':0}
  • id: 3, 数据 = {'cc': 7, 'bb': 0, 'cc':0}
  • id: 4, 数据 = {'bb': 7, 'bb': 0, 'cc':0}

这可以工作。

Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')

我建议使用 Coalesce。这个问题的作者想通了。下面有代码。

raw_sql = "+".join(["COALESCE((data->>%s)::int, 0)" for _ in ['aa', 'cc']) 
MyMoodel.objects.all()
.annotate(my_sum=RawSQL(raw_sql, params=('aa', 'cc')))
.order_by('my_sum')
于 2017-07-26T01:35:44.060 回答
1
 YourModel.objects.annotate(aa=RawSQL("((data->>'aa')::int)", (0,)),
                            cc=RawSQL("((data->>'cc')::int)", (0,))) \
                .aggregate(total=Sum('aa')+Sum('cc')).order_by('total')
于 2017-07-25T16:17:43.567 回答