slow select_related queries example debug django django-queryset django-orm query-performance

select_related - django slow queries



Seleccionar valores distintos de un campo de tabla (2)

Estoy luchando para entender el ORM de Django. Lo que quiero hacer es obtener una lista de valores distintos dentro de un campo de mi tabla ... el equivalente a uno de los siguientes:

SELECT DISTINCT myfieldname FROM mytable

(o alternativamente)

SELECT myfieldname FROM mytable GROUP BY myfieldname

Al menos me gustaría hacerlo de la manera Django antes de recurrir a sql en bruto. Por ejemplo, con una tabla:

id, calle, ciudad

1, calle principal, casco

2, otra calle, casco

3, Bibble Way, Leicester

4, Otra forma, Leicester

5, High Street, Londidium

Me gustaría obtener:

Hull, Leicester, Londidium.


Además de la respuesta todavía muy relevante de jujule , me parece muy importante conocer las implicaciones de order_by() en consultas distinct("field_name") . ¡Esta es, sin embargo, una función única de Postgres!

Si está utilizando Postgres y si define un nombre de campo para el que la consulta debe distinguirse, entonces order_by() debe comenzar con el mismo nombre de campo (o nombres de campo) en la misma secuencia (puede haber más campos después).

Nota

Cuando especifica nombres de campo, debe proporcionar un orden_by () en el QuerySet, y los campos en order_by () deben comenzar con los campos en distinct (), en el mismo orden.

Por ejemplo, SELECT DISTINCT ON (a) le proporciona la primera fila para cada valor en la columna a. Si no especifica un pedido, obtendrá una fila arbitraria.

Si quieres, por ejemplo, extraer una lista de ciudades en las que conoces tiendas, el ejemplo de jujule debería adaptarse a esto:

# returns an iterable Queryset of cities. models.Shop.objects.order_by(''city'').values_list(''city'', flat=True).distinct(''city'')


Digamos que tu modelo es ''Comprar''

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

Dado que puede tener el conjunto de atributos de ordering clase Meta , puede usar order_by() sin parámetros para borrar cualquier orden cuando se usa distinct() . Consulte la documentación en order_by()

Si no desea que se aplique ningún pedido a una consulta, ni siquiera el orden predeterminado, llame a order_by () sin parámetros.

y distinct() en la nota donde se analizan los problemas con el uso de distinct() con el pedido.

Para consultar su DB, solo tiene que llamar:

models.Shop.objects.order_by().values(''city'').distinct() # returns a dictionary

o

models.Shop.objects.order_by().values_list(''city'').distinct() # returns a list of tuples.

También puede agregar flat=True a values_list para tener una lista plana.

Consulte también: Obtener valores distintos de Queryset por campo