PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

django - aggrega le chiavi specifiche del campo json e l'ordine in base all'aggregazione

Ho capito che vuoi sommare un valore e un valore b per ogni riga e quindi ordinare ogni riga in base al valore della somma. vero?

-> ->> Ecco come selezionare la chiave o il valore in formato JSON in PostgreSQL (non so se funziona anche in MySQL o altri, normalmente ho lavorato con PostgreSQL). C'è una buona risorsa in qui . i tuoi dati in una colonna denominata 'data ' è {"aa":3, "bb":2, "cc":5} . quindi selezioni un valore tramite data->>'aa' . E se {'classification':{'pc':5000}} ? è necessario selezionare il valore del pc. Quindi data->'classification'->>'pc'

::la notazione è un'operazione di cast.

CAST(data->'aa' AS INTEGER)

data->'aa'::int

classe RawSQL(sql, parametri, output_field=Nessuno)

RawSQL("((data->>'aa'::int), (0,)") non significa che se aa non esiste, ha valore 0. 0 è parametri.

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

Bene, se puoi modificare i tuoi dati in questo modo

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

Questo può funzionare.

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

Ho suggerito di usare Coalesce. l'autore di questa domanda ha capito. C'è il codice qui sotto.

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