sql >> Databasteknik >  >> RDS >> PostgreSQL

django - aggregera json-fältspecifika nycklar och ordning efter aggregeringen

Jag förstod att man vill summera ett värde och b-värde för varje rad och sedan sortera varje rad efter summavärde. eller hur?

-> ->> Så här väljer du nyckel eller värde i JSON-format i PostgreSQL(Jag vet inte om det också fungerar i MySQL eller andra, jag arbetade normalt med PostgreSQL). Det finns bra resurs i här . dina data i en kolumn med namnet 'data ' är {"aa":3, "bb":2, "cc":5} . så du väljer ett värde med data->>'aa' . Vad händer om {'classification':{'pc':5000}} ? du måste välja pc-värde. Sedan data->'classification'->>'pc'

::notation är cast operation.

CAST(data->'aa' AS INTEGER)

data->'aa'::int

klass RawSQL(sql, params, output_field=Inget)

RawSQL("((data->>'aa'::int), (0,)") betyder inte att om aa inte finns har det 0-värde. 0 är params.

queryset.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))

Tja, om du kan ändra dina data så här

  • 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}

Detta kan fungera.

Contract.objects.annotate(
sumVal=RawSQL("((data->>'aa')::int)", (0,))+RawSQL("((data->>'cc')::int)",(0,)))
.order_by('sumVal')

Jag föreslog att du skulle använda Coalesce. författaren till denna fråga listade ut. Det finns kod nedan.

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')


  1. Returnera antalet berörda rader från en MERGE med cx_oracle

  2. Importera MS ACCESS DB till mySql?

  3. Konvertera sträng till Datetime-objekt i SQL

  4. Returnerar Oracle ref-markör och lägger till flera resultat