I have a table which same as bellow
id|user|datetime|action
this table records actions for each user and its time I want to get latest actions which are done by all users. I have tested these methods
Entry.objects.order_by('datetime','user').distinct('user')
and
Entry.objects.latest('datetime').distinct('user')
but both of them returns errors. for example the second try says :
SELECT DISTINCT ON expressions must match initial ORDER BY expressions
How can I filter rows by latest actions which are done by all users?
Try with below code:
Entry.objects.all().order_by('user', '-datetime').distinct('user')
From django doc we have :
When you specify field names, you must provide an order_by() in the QuerySet, and the fields in order_by() must start with the fields in distinct(), in the same order.
Related
I have a Message class which has fromUser, toUser, text and createdAt fields.
I want to imitate a whatsapp or iMessage or any SMS inbox, meaning I want to fetch the last message for each conversation.
I tried:
messages = Message.objects.order_by('createdAt').distinct('fromUser', 'toUser')
But this doesn't work because of SELECT DISTINCT ON expressions must match initial ORDER BY expressions error.
I don't really understand what it means, I also tried:
messages = Message.objects.order_by('fromUser','toUser','createdAt').distinct('fromUser', 'toUser')
and such but let me not blur the real topic here with apparently meaningless code pieces. How can I achieve this basic or better said, general well-known, result?
Your second method is correct. From the Django docs:
When you specify field names, you must provide an order_by() in the QuerySet, and the fields in order_by() must start with the fields in distinct(), in the same order.
For example, SELECT DISTINCT ON (a) gives you the first row for each value in column a. If you don’t specify an order, you’ll get some arbitrary row.
This means that you must include the same columns in your order_by() method that you want to use in the distinct() method. Indeed, your second query correctly includes the columns in the order_by() method:
messages = Message.objects.order_by('fromUser','toUser','createdAt').distinct('fromUser', 'toUser')
In order to fetch the latest record, you need to order the createdAt column by descending order. The way to specify this order is to include a minus sign on the column name in the order_by() method (there is an example of this in the docs here). Here's the final form that you should use to get your list of messages in latest-first order:
messages = Message.objects.order_by('fromUser','toUser','-createdAt').distinct('fromUser', 'toUser')
How can I make an order_by like this ....
p = Product.objects.filter(vendornumber='403516006')\
.order_by('-created').distinct('vendor__name')
The problem is that I have multiple vendors with the same name, and I only want the latest product by the vendor ..
Hope it makes sense?
I got this DB error:
SELECT DISTINCT ON expressions must match initial ORDER BY expressions
LINE 1: SELECT DISTINCT ON ("search_vendor"."name")
"search_product"...
Based on your error message and this other question, it seems to me this would fix it:
p = Product.objects.filter(vendornumber='403516006')\
.order_by('vendor__name', '-created').distinct('vendor__name')
That is, it seems that the DISTINCT ON expression(s) must match the leftmost ORDER BY expression(s). So by making the column you use in distinct as the first column in the order_by, I think it should work.
Just matching leftmost order_by() arg and distinct() did not work for me, producing the same error (Django 1.8.7 bug or a feature)?
qs.order_by('project').distinct('project')
however it worked when I changed to:
qs.order_by('project__id').distinct('project')
and I do not even have multiple order_by args.
In case you are hoping to use a separate field for distinct and order by another field you can use the below code
from django.db.models import Subquery
Model.objects.filter(
pk__in=Subquery(
Model.objects.all().distinct('foo').values('pk')
)
).order_by('bar')
I had a similar issue but then with related fields. With just adding the related field in distinct(), I didn't get the right results.
I wanted to sort by room__name keeping the person (linked to residency ) unique. Repeating the related field as per the below fixed my issue:
.order_by('room__name', 'residency__person', ).distinct('room__name', 'residency__person')
See also these related posts:
ProgrammingError: when using order_by and distinct together in django
django distinct and order_by
Postgresql DISTINCT ON with different ORDER BY
At the moment I have a query that selects distinct values from a model:
Meeting.objects.values('club').distinct()
In addition to the 'club' field, I also wish to select a 'time' field. In other words I wish to select distinct values of the 'club' field and the associated 'time' field. For example for:
CLUB,TIME
ABC1,10:35
ABC2,10:45
ABC2,10:51
ABC3,11:42
I would want:
ABC1,10:35
ABC2,10:45
ABC3,11:42
What is the syntax for this?
This is possible, but only if your database backend is PostgreSQL. Here how it can be done:
Meeting.objects.order_by('club', 'time').values('club', 'time').distinct('club')
Look documentation for distinct
I have a django model query that needs to fetch me the distinct rows from a particular table, but for some reason its not fetching it.
Let me know your inputs
Query
Volunteercontacts.objects.order_by('name')- gives me the expected answer ie;ordering by name
Volunteercontacts.objects.order_by('name').distinct('name')- does not eliminate the duplicate
You should differentiate between distinct Volunteercontacts models and distinct name column values.
For distinct Volunteercontacts models you can use distinct(), but in this case has no effect:
Volunteercontacts.objects.order_by('name').distinct()
For distinct columns values you can use a dictionary or array of value list:
Volunteercontacts.objects.values_list('name',
flat=True).order_by('name').distinct()
Also, remember that the ability to specify field names in distinct method is only available in PostgreSQL.
Django 1.4 provides the expected behaviour in the original question (assuming you are using Posgtres):
https://docs.djangoproject.com/en/1.4/ref/models/querysets/#distinct
I need to order_by a field comparison such that all fields matching a certain value are displayed at the top.
The SQL to do this is SELECT * FROM messages ORDER BY message='alsfkjsag' DESC
There are at least two ways to do it:
Custom SQL with UNION:
combine two selects
one who contains all rows which have your desired message
the other with all rows who have another message
Add a dynmaic Field to the QuerySet
extra(select={"is_message":"message='alsfkjsag'"})
and then order_by('is_message')
or in short:
Messages.objects.extra(select={"is_message":"message='alsfkjsag'"})
.order_by('is_message')