Seleziona valori distinti da un campo di tabella
-
20-09-2019 - |
Domanda
Faccio fatica a capire l'ORM di Django.Quello che voglio fare è ottenere un elenco di valori distinti all'interno di un campo sulla mia tabella ....l'equivalente di uno dei seguenti:
SELECT DISTINCT myfieldname FROM mytable
(o in alternativa)
SELECT myfieldname FROM mytable GROUP BY myfieldname
Mi piacerebbe almeno farlo alla maniera Django prima di ricorrere a SQL grezzo.Ad esempio, con una tabella:
id, strada, città
1, via principale, Scafo
2, Altra strada, Hull
3, Via della Bibbia, Leicester
4, Un altro modo, Leicester
5, High Street, Londidium
vorrei ottenere:
Scafo, Leicester, Londidium.
Soluzione
Dite il vostro modello è 'Shop'
class Shop(models.Model):
street = models.CharField(max_length=150)
city = models.CharField(max_length=150)
# some of your models may have explicit ordering
class Meta:
ordering = ('city')
Dal momento che si può avere il set di attributi di classe Meta
ordering
, è possibile utilizzare order_by()
senza parametri per cancellare qualsiasi ordine quando si utilizza distinct()
. Vedere la documentazione sotto order_by
()
Se non si desidera alcun ordinamento da applicare a una query, nemmeno l'ordinamento predefinito, chiamare order_by () senza parametri.
distinct()
nella nota in cui si discute questioni con l'utilizzo di distinct()
con ordine.
Per interrogare il DB, basta chiamare:
models.Shop.objects.order_by().values('city').distinct()
Si restituisce un Dictionnary
o
models.Shop.objects.order_by().values_list('city').distinct()
Questo restituisce un ValuesListQuerySet
che si può lanciare ad un list
.
È inoltre possibile aggiungere flat=True
a values_list
per appiattire i risultati.
Si veda anche: ottenere i valori distinti di Queryset di campo
Altri suggerimenti
Oltre a ciò che è ancora molto rilevante risposta di jujule, Trovo molto importante essere consapevoli anche delle implicazioni di order_by()
SU distinct("field_name")
interrogazioni. Questa è, tuttavia, una funzionalità esclusiva di Postgres!
Se stai utilizzando Postgres e se definisci un nome di campo per il quale la query dovrebbe essere distinta, allora order_by()
deve iniziare con lo stesso nome di campo (o nomi di campo) nella stessa sequenza (potrebbero esserci più campi successivamente).
Nota
Quando si specificano i nomi dei campi, è necessario fornire un ordine_by () nel querySet e i campi in order_by () devono iniziare con i campi in distinto (), nello stesso ordine.
Ad esempio, selezionare Distinto su (a) ti dà la prima riga per ciascun valore nella colonna A.Se non specifichi un ordine, otterrai una riga arbitraria.
Se vuoi, ad esempio, estrarre un elenco di città in cui conosci negozi, l'esempio di jujule dovrebbe essere adattato a questo:
# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')
Per esempio:
# select distinct code from Platform where id in ( select platform__id from Build where product=p)
pl_ids = Build.objects.values('platform__id').filter(product=p)
platforms = Platform.objects.values_list('code', flat=True).filter(id__in=pl_ids).distinct('code')
platforms = list(platforms) if platforms else []