PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

django - aggregieren Sie json-feldspezifische Schlüssel und sortieren Sie sie nach der Aggregation

Ich habe verstanden, dass Sie einen Wert und einen b-Wert für jede Zeile zusammenfassen und dann jede Zeile nach Summenwert ordnen möchten. richtig?

-> ->> So wählen Sie Schlüssel oder Werte im JSON-Format in PostgreSQL aus (ich weiß nicht, ob es auch in MySQL oder anderen funktioniert, ich habe normalerweise mit PostgreSQL gearbeitet). Es gibt eine gute Ressource in hier . Ihre Daten in einer Spalte namens 'data ' ist {"aa":3, "bb":2, "cc":5} . Sie wählen also einen Wert durch data->>'aa' aus . Was wäre, wenn {'classification':{'pc':5000}} ? Sie müssen den PC-Wert auswählen. Dann data->'classification'->>'pc'

::Notation ist Cast-Operation.

CAST(data->'aa' AS INTEGER)

data->'aa'::int

Klasse RawSQL(sql, params, output_field=None)

RawSQL("((data->>'aa'::int), (0,)") bedeutet nicht, dass wenn aa nicht existiert, es den Wert 0 hat. 0 ist params.

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

Nun, wenn Sie Ihre Daten so ändern können

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

Das kann funktionieren.

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

Ich habe vorgeschlagen, Coalesce zu verwenden. der Autor dieser Frage herausgefunden. Es gibt Code unten.

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