Zrozumiałem, że chcesz zsumować wartość i wartość b dla każdego wiersza, a następnie uporządkować każdy wiersz według wartości sumy. prawda?
-> ->> Oto jak wybrać klucz lub wartość w formacie JSON w PostgreSQL (nie wiem, czy działa również w MySQL lub innych, normalnie pracowałem z PostgreSQL). W tutaj
. Twoje dane w kolumnie o nazwie „
data
' to {"aa":3, "bb":2, "cc":5}
. więc wybierasz wartość aa przez data->>'aa'
. Co jeśli {'klasyfikacja':{'pc':5000}}
? musisz wybrać wartość pc. Następnie data->'classification'->>'pc'
::notacja to operacja rzutowania.
CAST(data->'aa' AS INTEGER)
data->'aa'::int
class RawSQL(sql, params, output_field=Brak)
RawSQL("((data->>'aa'::int), (0,)") nie oznacza, że jeśli aa nie istnieje, to ma wartość 0. 0 to parametry.
queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
Cóż, jeśli możesz zmodyfikować swoje dane w ten sposób
- id:1, data ={'aa':1, 'bb':2, 'cc':4}
- id:2, data ={'aa':3, 'bb':2, 'cc':0}
- id:3, data ={'cc':7, 'bb':0, 'cc':0}
- id:4, data ={'bb':7, 'bb':0, 'cc':0}
To może działać.
Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')
Zasugerowałem użycie Coalesce. zorientował się autor tego pytania. Poniżej znajduje się kod.
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')