Reputation: 15
Hi I have two tables one called FILES and one called ACTIVITY.
There will be multiple entries of ACTIVITY for each FILE.
Here's the table data example:
FILES:
id | name | status |
---|---|---|
1 | File 1 | Pending |
2 | File 2 | Pending |
3 | File 3 | Returned |
ACTIVITY:
id | createtime | fileid | type | comment |
---|---|---|---|---|
1 | 2021-06-30 15:00:30 | 1 | User | Some data |
2 | 2021-06-30 14:02:30 | 1 | Admin | Some data |
3 | 2021-06-30 13:03:00 | 2 | User | Some data |
I'm trying to retrieve all the data from FILES, with two additional fields per row:
I've achieved this through subqueries but now that the ACTIVITY table is > 20,000 records query times have slowed badly.
Createtime and fileid fields are indexes on ACTIVITY.
Here's my existing SQL:
SELECT *,
(SELECT createtime FROM activity WHERE fileid = a.id ORDER BY createtime DESC LIMIT 1) as latestactivity,
(SELECT createtime FROM activity WHERE fileid = a.id AND type = "User" ORDER BY createtime DESC LIMIT 1) as latestuseractivity
FROM files AS a
ORDER BY FIELD(status, "Pending", "Returned"), latestactivity DESC;
I'm struggling to get my head around writing this in using JOIN to reduce the query time.
Any advice or help will be much appreciated. Thanks!
Upvotes: 0
Views: 69
Reputation: 116
Use JOIN
with GROUP BY
and CASE
SELECT f.*,
MAX(a.createtime) AS latestactivity,
MAX(CASE
WHEN a.type = 'User' THEN a.createtime
END) AS latestuseractivity
FROM
FILES f
JOIN ACTIVITY a
ON f.id = a.fileid
GROUP BY f.id, f.name, f.status
-- ORDER BY ...
Upvotes: 2