Jeg forstod, at du vil opsummere en værdi og b-værdi for hver række og derefter bestille hver række efter sumværdi. ikke?
-> ->> Sådan vælger du nøgle eller værdi i JSON-format i PostgreSQL (jeg ved ikke om det også virker i MySQL eller andre, jeg arbejdede normalt med PostgreSQL). Der er en god ressource i her
. dine data i en kolonne med navnet '
data
' er {"aa":3, "bb":2, "cc":5}
. så du vælger en værdi ved data->>'aa'
. Hvad hvis {'classification':{'pc':5000}}
? du skal vælge pc-værdi. Derefter data->'classification'->>'pc'
::notation er cast operation.
CAST(data->'aa' AS INTEGER)
data->'aa'::int
klasse RawSQL(sql, params, output_field=Ingen)
RawSQL("((data->>'aa'::int), (0,)") betyder ikke, at hvis aa ikke eksisterer, har den 0 værdi. 0 er params.
queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
Nå, hvis du kan ændre dine data på denne måde
- 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}
Dette kan virke.
Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')
Jeg foreslog at bruge Coalesce. forfatteren af dette spørgsmål fandt ud af. Der er kode nedenfor.
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')