MySql sort on join? [duplicate] - mysql

This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Closed 6 years ago.
I have two tables jobs, notes.
I want to output a list of jobs that are of status='lost' along with the most recent note for that job (based on the date the note was created).
Here's my query:
select jobs.id, jobs.name, jobs.status
inner join notes on jobs.id=notes.jobId
where jobs.status='lost'
group by jobs.id
order by notes.createDate DESC
I would have thought that the output would show the most recent note for a given job. But it shows the first note for that job. I have changed sort from DESC to ASC just to see what happens...and the output is the same.
Then I tried to nest a select from notes inside the main select..and it hung.
This should be easy and I am sure it is..what am I missing ?

There is many options to solve this, but you may use a sub query.
select jobs.id, jobs.name, jobs.status
(select noteField from notes on jobs.id=notes.jobId order by createDate desc limit 1) note
where jobs.status='lost'

When I'm in a similar boat, I've resorted to using a subquery on the join:
select jobs.id, jobs.name, jobs.status
from jobs
inner join notes on jobs.id = notes.jobId
and notes.createDate = (select max(notes.createDate)
from notes
where jobs.id = notes.createDate
group by notes.jobId)
where jobs.status='lost'
group by jobs.id
order by notes.createDate DESC

Related

How to apply ORDER to GROUP BY [duplicate]

This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Closed 2 years ago.
I have the article table, each having a related category (or NULL if not categorized - these articles don't interest me in this case).
I want to get 8 newest articles each from one category in a way that there is always only one article for one category (i.e. never 2 articles from the same category).
This query almost work:
SELECT article.id, article.title, category_container.title FROM `article`
JOIN `category_container` ON category_container.id = article.category_id
WHERE `category_id` IS NOT NULL GROUP BY `category_id` ORDER BY article.created_at DESC LIMIT 8
The problem is, ORDER doesn't work. I want newest, it returns me the earliest ones (with the smallest id, while it should be the opposite).
So, how to apply ORDER to GROUP BY?
You don't. Your query is broken -- and in the latest versions of MySQL you would properly get an error.
Instead use a filtering method to get the latest rows. Here is a method using a correlated subquery:
SELECT a.id, a.title, cc.title
FROM article a JOIN
category_container cc
ON cc.id = a.category_id
WHERE a.created_at = (SELECT MAX(a2.created_at)
FROM article a2
WHERE a2.category_id = a.category_id
)
ORDER BY a.created_at DESC
LIMIT 8;
For performance, you want an index on article(category_id, created_at).
In the more recent versions, this would be even simpler using ROW_NUMBER():
SELECT a.id, a.title, cc.title
FROM (SELECT a.*,
ROW_NUMBER() OVER (PARTITION BY a.category_id ORDER BY a.created_at DESC) as seqnum
FROM article a
) a JOIN
category_container cc
ON cc.id = a.category_id
WHERE seqnum = 1;
Given that your query runs with no errors, you are probably using an older version of MySQL and this won't work.

How to remove duplicate results? [duplicate]

This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Closed 3 years ago.
I'm coding a message system using mysql.
Everything works fine when I list users whom I'm conversing with, until I want to add date of the last or the start of conversation.
When I add a.date I get duplicate results when the date isnt the same.
Here is my sqlfiddle
Since, you were pulling only user_id then in both cases (send/recieve) it was giving you distinct record. But now with date it is no more distinct. you need to do something like:
SELECT temp.id_user, MAX(temp.date) as date
FROM
(
SELECT users.id_user,
a.date
FROM users
LEFT JOIN message AS a
ON users.id_user = a.id_user_recipient
LEFT JOIN message AS b
ON a.id_user_recipient = b.id_user_sender
WHERE a.id_user_sender = 1
UNION DISTINCT
SELECT users.id_user,
a.date
FROM users
LEFT JOIN message AS a
ON users.id_user = a.id_user_sender
LEFT JOIN message AS b
ON a.id_user_sender = b.id_user_recipient
WHERE a.id_user_recipient = 1
) as temp
GROUP BY temp.id_user;
Grabbing max(date) will ensure to return only one record as with group by

computed column to use further in mysql query [duplicate]

This question already has answers here:
Can I reuse a calculated field in a SELECT query?
(7 answers)
Closed 3 years ago.
I want to know how can i use two columns already computed in sql query to get one more result from their values.
my query is
SELECT s.date date
, p.id
, SUM(COALESCE(p.avgcost,0)) costofsale
, SUM( COALESCE(s.actual_payable, 0 ) ) total_sales
, (total_sales - costofsale) tots
FROM sales s
LEFT
JOIN sale_items si
on si.sale_id = s.id
LEFT
JOIN products p
on p.id = si.product_id
WHERE DATE(s.date) = DATE('2019-09-10 14:48:50')
I want to get the result from total_sales - costofsale that is already computed in query.
I don't want to alter or update my table.
I just need to use those two columns to give me the result by calculating them.
I have not found any solution over google.
MySQL 8 includes WITH statements which allows for creating calculated values without using variables.
WITH statement VS subquery

MySQL: Order by max date of a joined table [duplicate]

This question already has answers here:
Ordering a MySQL result set by a MAX() value of another table
(2 answers)
Closed 4 years ago.
I have two tables - groups and messages.
Messages has the following fields group_id and date_created. So a lot of messages can be added to a single group. I want to select all groups from table - most relevant on top, i.e. order by latest message date. I've tried something like this
SELECT g.*, MAX(m.date_created) AS mdt FROM groups g
LEFT JOIN messages m ON g.id = m.group_id
ORDER BY mdt DESC;
But this query returns only one row and max message date from the whole table.
You are missing group by:
SELECT g.*, MAX(m.date_created) AS mdt
FROM groups g LEFT JOIN
messages m
ON g.id = m.group_id
GROUP BY g.id
ORDER BY mdt DESC;

mysql order by values and then show the rest [duplicate]

This question already has answers here:
Case statement in MySQL
(6 answers)
Closed 4 years ago.
I want to order the results of a mysql query
1) to show first entrys wich match a given condition and order them randomly
2) and then show the rest of the results ordered by date desc
i tryed already this:
Select * from post inner join user on post.user_id = user.id order by user.type = "top" desc, created desc;
many thanks
Use a case statement
select * from post
inner join user on post.user_id = user.id
order by case when user.type = 'top'
then 1
else 2
end asc,
created desc;