SQL查询帮助 - T.a,T.c分组的T.a的前N个值

时间:2011-01-10 17:45:49

标签: sql mysql

我有一个名为TaskLog的表,它保存各种计划任务的结果。它(为了这个问题的目的)这些列:

  • TaskLogID:此记录的唯一ID
  • TaskID:运行的任务的ID
  • HostName:运行它的主机的名称
  • RunDate:运行任务的日期和时间
  • 输出:此次运行的输出

为了从每个任务的最新运行中获取输出,我一直在执行多个查询,直到我计算出更快的单个查询:

SELECT TaskLog.TaskID, TaskLog.HostName, TaskLog.Output
FROM TaskLog
INNER JOIN (
    SELECT TaskLogID, TaskID, HostName, MAX(RunDate)
    FROM TaskLog
    GROUP BY TaskID, HostName
) AS Latest
USING (TaskLogID)

现在我想获得每个任务的最后 N 运行的输出,对于一些固定的 N ,而不仅仅是最新的运行。有没有办法在单个查询中执行此操作?

TIA

2 个答案:

答案 0 :(得分:0)

这就是MySQL缺少诸如Row_Number()之类的窗口函数的地方。

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

假设TaskLogId是一个自动增量列,您可以使用以下内容(在此示例中,我假设您请求了前5项):

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

答案 1 :(得分:0)

未经测试,因为我没有在此计算机上安装MySQL(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;