各行の値とb値を合計してから、合計値で各行を並べ替える必要があることを理解しました。でしょ?
->->>コード> これは、PostgreSQLでJSON形式のキーまたは値を選択する方法です(MySQLなどでも機能するかどうかはわかりませんが、通常はPostgreSQLで使用していました)。こちら
。 '
data
という名前の列のデータ 'は{"aa":3、 "bb":2、 "cc":5}
です 。したがって、 data->>'aa'
でaa値を選択します 。 {'classification':{'pc':5000}}
の場合はどうなりますか ? pc値を選択する必要があります。次に、 data->'classification'->>'pc'
::表記はキャスト操作です。
CAST(data->'aa' AS INTEGER)
data->'aa'::int
クラスRawSQL(sql、params、output_field =None)
RawSQL( "((data->>'aa' ::int)、(0、)")は、aaが存在しない場合、値が0であることを意味しません。0はパラメータです。
queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
さて、このようにデータを変更できれば
- 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}
これは機能します。
Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')
Coalesceの使用を提案しました。この質問の作者は理解しました。以下にコードがあります。
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')