开发者

SQL query help - top N values of T.a grouped by T.b, T.c

开发者 https://www.devze.com 2023-02-04 12:44 出处:网络
I have a table called TaskLog that holds the results of various scheduled tasks. It has (for the purposes of this question) these columns:

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
0

精彩评论

暂无评论...
验证码 换一张
取 消