SQL query help - top N values of T.a grouped by T.b, T.c
I have a table called TaskLog that holds the results of various scheduled tasks. It has (for the purposes of this question) these columns:
- TaskLogID: unique ID for this record
- TaskID: ID of the task that ran
- HostName: name of the host on which it ran
- RunDate: date and time on which the task was run
- Output: output of this run
In order to get the output from the latest run of each task, I had been executing multiple queries, until I worked out this single query which is much faster:
SELECT TaskLog.TaskID, TaskLog.HostName, TaskLog.Output
FROM TaskLog
INN开发者_开发问答ER JOIN (
SELECT TaskLogID, TaskID, HostName, MAX(RunDate)
FROM TaskLog
GROUP BY TaskID, HostName
) AS Latest
USING (TaskLogID)
Now I'd like to get the output from each of the last N runs of each task, for some fixed N, instead of just the latest run. Is there a way to do this in a single query?
TIA
Untested as I don't have MySQL installed on this machine (based on here)
select TaskLogID,
TaskID,
HostName,
RunDate
from (select TaskLogID,
TaskID,
HostName,
RunDate,
@num := if(@group = concat(TaskID, HostName), @num + 1, 1) as row_number,
@group := concat(TaskID, HostName) as dummy
from TaskLog) as x
where row_number <= 5;
This is where MySQL lack of window functions such as Row_Number() really hurts.
Select T.TaskLogId, T.TaskId, T.HostName, T.RunDate
From TaskLog As T
Join (
Select T1.TaskLogId
, (Select Count(*)
From TaskLog as T2
Where T2.TaskId = T1.TaskId
And T2.RunDate < T1.RunDate) + 1 As Rnk
From TaskLog As T1
) As RankedTasks
On RankedTasks.TaskLogId = T.TaskLogId
And RankedTasks.Rnk <= <somevalue>
Order By T.TaskId, T.RunDate
ADDITION
Assuming that TaskLogId is an auto increment column, you might be able to something like the following (In this example, I assumed you requested the top 5 items):
Select T.TaskLogId, T.TaskId, T.HostName, T.RunDate
From TaskLog As T
Join (
Select Tasks1.TaskId
, (
Select T4.TaskLogId
From TaskLog As T4
Where T4.TaskId = Tasks.TaskId
Order By T4.RunDate Desc
Limit 5, 1
) As UpperTaskLogId
From (
Select T3.TaskId
From TaskLog As T3
Group By T3.TaskId
) As Tasks1
) As LastId
On LastId.TaskId = T.TaskId
And LastId.UpperTaskLogId >= T.TaskLogId
精彩评论