Saya mengerti bahwa Anda ingin menjumlahkan nilai dan nilai b untuk setiap baris dan kemudian memesan setiap baris dengan nilai jumlah. kan?
-> ->>
Ini adalah cara memilih kunci atau nilai dalam format JSON di PostgreSQL (Saya tidak tahu apakah itu juga berfungsi di MySQL atau yang lain, saya biasanya bekerja dengan PostgreSQL). Ada sumber yang bagus di di sini
. data Anda di kolom bernama 'data
' adalah {"aa":3, "bb":2, "cc":5}
. jadi Anda memilih nilai aa dengan data->>'aa'
. Bagaimana jika {'classification':{'pc':5000}}
? Anda harus memilih nilai pc. Kemudian data->'classification'->>'pc'
::notasi adalah operasi cast.
CAST(data->'aa' AS INTEGER)
data->'aa'::int
kelas RawSQL(sql, params, output_field=None)
RawSQL("((data->>'aa'::int), (0,)") bukan berarti jika aa tidak ada, ia memiliki nilai 0. 0 adalah params.
queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
Nah, jika Anda dapat memodifikasi data Anda seperti ini
- 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}
Ini bisa berhasil.
Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')
Saya menyarankan menggunakan Coalesce. penulis pertanyaan ini tahu. Ada kode di bawah ini.
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')