Ik begreep dat je een waarde en een b-waarde voor elke rij wilt optellen en vervolgens elke rij wilt rangschikken op somwaarde. toch?
-> ->>
Zo selecteert u de sleutel of waarde in JSON-indeling in PostgreSQL (ik weet niet of het ook werkt in MySQL of anderen, ik werkte normaal gesproken met PostgreSQL). Er is een goede bron in hier
. uw gegevens in een kolom met de naam 'data
' is {"aa":3, "bb":2, "cc":5}
. dus je selecteert aa-waarde door data->>'aa'
. Wat als {'classification':{'pc':5000}}
? u moet pc-waarde selecteren. Dan data->'classification'->>'pc'
::notatie is cast-bewerking.
CAST(data->'aa' AS INTEGER)
data->'aa'::int
class RawSQL(sql, params, output_field=None)
RawSQL("((data->>'aa'::int), (0,)") betekent niet dat als aa niet bestaat, het een waarde 0 heeft. 0 is params.
queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
Wel, als u uw gegevens op deze manier kunt wijzigen
- 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}
Dit kan werken.
Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')
Ik stelde voor om Coalesce te gebruiken. de auteur van deze vraag bedacht. Er is onderstaande code.
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')