Ho capito che vuoi sommare un valore e un valore b per ogni riga e quindi ordinare ogni riga in base al valore della somma. vero?
-> ->>
Ecco come selezionare la chiave o il valore in formato JSON in PostgreSQL (non so se funziona anche in MySQL o altri, normalmente ho lavorato con PostgreSQL). C'è una buona risorsa in qui
. i tuoi dati in una colonna denominata 'data
' è {"aa":3, "bb":2, "cc":5}
. quindi selezioni un valore tramite data->>'aa'
. E se {'classification':{'pc':5000}}
? è necessario selezionare il valore del pc. Quindi data->'classification'->>'pc'
::la notazione è un'operazione di cast.
CAST(data->'aa' AS INTEGER)
data->'aa'::int
classe RawSQL(sql, parametri, output_field=Nessuno)
RawSQL("((data->>'aa'::int), (0,)") non significa che se aa non esiste, ha valore 0. 0 è parametri.
queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
Bene, se puoi modificare i tuoi dati in questo modo
- 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}
Questo può funzionare.
Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')
Ho suggerito di usare Coalesce. l'autore di questa domanda ha capito. C'è il codice qui sotto.
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')