Tôi hiểu rằng bạn muốn tính tổng một giá trị và giá trị b cho mỗi hàng và sau đó sắp xếp từng hàng theo giá trị tổng. đúng không?
-> ->>
Đây là cách chọn khóa hoặc giá trị ở định dạng JSON trong PostgreSQL (Tôi không biết liệu nó cũng hoạt động trong MySQL hay những người khác, tôi thường làm việc với PostgreSQL). Có tài nguyên tốt trong tại đây
. dữ liệu của bạn trong cột có tên 'data
'là {"aa":3, "bb":2, "cc":5}
. vì vậy bạn chọn giá trị aa theo data->>'aa'
. Điều gì sẽ xảy ra nếu {'classification':{'pc':5000}}
? bạn cần chọn giá trị máy tính. Sau đó, data->'classification'->>'pc'
::ký hiệu là hoạt động ép kiểu.
Dữ liệuCAST(data->'aa' AS INTEGER)
data->'aa'::int
lớp RawSQL (sql, params, output_field =None)
RawSQL ("((data ->> 'aa' ::int), (0,)") không có nghĩa là nếu aa không tồn tại, nó có giá trị 0. 0 là tham số.
queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
Chà, nếu bạn có thể sửa đổi dữ liệu của mình như thế này
- 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}
Điều này có thể hoạt động.
Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')
Tôi đã đề xuất sử dụng Coalesce. tác giả của câu hỏi này đã tìm ra. Có mã bên dưới.
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')