Разбрах, че искате да сумирате стойност и b стойност за всеки ред и след това да подредите всеки ред по сумарна стойност. нали?
-> ->>
Ето как да изберете ключ или стойност във формат JSON в PostgreSQL (не знам дали работи и в 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, параметри, 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, data ={'cc':7, 'bb':0, 'cc':0}
- id:4, data ={'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')