get distinct "title" in mysql in django - mysql

I have used django to develop a web app.
I want to get the distinct "title" form the queryset get by filter.
But I use mysql so could not pass "title" to distict.
How could I filter the queryset with the distinct "title"?
query_set = CourseInfo.objects.filter(discipline_id=id).distinct('title')
return render(request, 'main.html',
context={'query_set':query_set})
I get error for this in mysql as it may only used in postgresql
`

It will give you distinct titles:
titles = CourseInfo.objects.filter(
discipline_id=id
).order_by('title').values('title').distinct()
Note:
there is no such thing called SELECT DISTINCT ON in MySQL.
You can only use it in Postgresql but maybe GROUP BY helps you for converting SELECT DISTINCT ON query to MySQL query.
Check out this link then you kinda can convert this query to MySQL query.

Related

want to get data from mysql as string

DB::table('follow_ups')
->select(
'created_at as start',
DB::raw('count(*) as title')
)->groupBy('created_at')->get()->toArray();
above query is returning title as integer, i want this value as string
COUNT(*) is an aggregation function that will count distinct titles in a group. If you want to get all titles you need a different aggregation function that can (somehow) return all members of the group. There is one option that is generally available (i.e. even in older MySQL versions):
GROUP_CONCAT
DB::table('follow_ups')
->select(
'created_at as start',
DB::raw('GROUP_CONCAT(title) as title')
)->groupBy('created_at')->get()->toArray();
This will return all group members concatenated via the delimiter you specify (default is , if you don't specify one)
Newer MySQL versions also have JSON_ARRAYAGG
DB::table('follow_ups')
->select(
'created_at as start',
DB::raw('JSON_ARRAYAGG(title) as title')
)->groupBy('created_at')->get()->toArray();
This will return the result as a json array which you can then decode using json_decode($row['title'],true)
The advantage of the 2nd method is that it's easier to get individual values of the group in the cases where the group members contain the delimiter e.g. there's some title that contains a comma and would therefore make GROUP_CONCAT a bit useless.
Note: Both these functions are MySQL/MariaDB specific as far as I know so if you plan to make your database portable you might want to avoid them and look for alternatives that are ANSI SQL compliant.

how to get a particular field from django model

I want a command for getting a query set from the model.
The SQL command will be like
SELECT teamName FROM TABLE WHERE userName=userName;
I found the answer
teamNameQuery=userInfo.objects.filter(userName=userName).values('teamName').first()
you can retrive list of field from model by using values_list
Model.Objects.filter(userName = userName).values_list('teamName')

Django mysql count distinct gives different result to postgres

I'm trying to count distinct string values for a fitered set of results in a django query against a mysql database versus the same data in a postgres database. However, I'm getting really confusing results.
In the code below, NewOrder represents queries against the same data in a postgres database, and OldOrder is the same data in a MYSQL instance.
( In the old database, completed orders had status=1, in the new DB complete status = 'Complete'. In both the 'email' field is the same )
OldOrder.objects.filter(status=1).count()
6751
NewOrder.objects.filter(status='Complete').count()
6751
OldOrder.objects.filter(status=1).values('email').distinct().count()
3747
NewOrder.objects.filter(status='Complete').values('email').distinct().count()
3825
print NewOrder.objects.filter(status='Complete').values('email').distinct().query
SELECT DISTINCT "order_order"."email" FROM "order_order" WHERE "order_order"."status" = Complete
print OldSale.objects.filter(status=1).values('email').distinct().query
SELECT DISTINCT "order_order"."email" FROM "order_order" WHERE "order_order"."status" = 1
And here is where it gets really bizarre
new_orders = NewOrder.objects.filter(status='Complete').values_list('email', flat=True)
len(set(new_orders))
3825
old_orders = OldOrder.objects.filter(status=1).values_list('email',flat=True)
len(set(old_orders))
3825
Can anyone explain this discrepancy? And possibly point me as to why results would be different between postgres and mysql? My only guess is a character encoding issue, but I'd expect the results of the python set() to also be different?
Sounds like you're probably using a case-insensitive collation in MySQL. There's no equivalent in PostgreSQL; the closest is the citext data type, but usually you just compare lower(...) of strings, or use ILIKE for pattern matching.
I don't know how to say it in Django, but I'd see if the count of the set of distinct lowercased email addresses is the same as the old DB.
According to the Django docs something like this might work:
NewOrder.objects.filter(status='Complete').values(Lower('email')).distinct()

get all records matching the query string and display like in google suggest by google

What I want to do is, somewhat similar to google suggest.
My client page will submit the search text through ajax to server. The server will grab that text and query all the records matching that string and return back to client page.
e.g.
text_frm_client = "Ba". The query will show all the records beginning with "Ba"
The raw sql query to achieve my problem is
**Select * from table_name where column1 LIKE "Ba%" or column2 LIKE "Ba%"**
Now I want to port this query to django model. What I found is somewhat somewhat similar.
https://docs.djangoproject.com/en/dev/ref/models/querysets/#std:fieldlookup-contains
But this is only for one field. How can I accomplish the sql query with django model.
You can use the Q
data = MyModel.objects.filter(
Q(column1__contains="Ba") |
Q(column2__contains="Ba")
)

Django raw sql query

I have a this model:
class Document(models.Model):
data = models.TextField()
users = models.ManyToManyField(User)
How would you convert the following query for the model above to raw sql?
Document.objects.annotate(num_users=Count(users))
I need to switch this to raw sql because there is a bug in django when using MySql that makes annotate very slow.
But I'm not sure how to handle the many to many field in raw sql..
Document.objects.raw('SELECT ...')
The easiest way to translate your Django query to SQL is to simply look at the SQL that Django generates: How can I see the raw SQL queries Django is running?
you can get corresponding query the way mentioned below:
queryset = Document.objects.annotate(num_users=Count(users))
sql_query = queryset.query
print(sql_query)