按最大列显示前1名

时间:2017-10-20 08:35:52

标签: sql sql-server tsql group-by duplicates

我有一个查询,可以获取有关特定工作的一些信息。

但是,我很难获得每项工作的最高记录(基于最新的' LastRun'字段)。

有关如何实现这一目标的任何帮助?

我的查询是:

SELECT 
job.Name,
CAST(CAST(hist.run_date AS CHAR(8))
+ ' ' 
+ STUFF(
STUFF(RIGHT('000000' + CAST(hist.run_time AS VARCHAR(6)),  6)
, 3, 0, ':')
, 6, 0, ':')
AS DATETIME) AS LastRun,
CASE hist.run_status 
   WHEN 0 THEN 'Failed' 
   WHEN 1 THEN 'Success' 
   WHEN 2 THEN 'Retry' 
   WHEN 3 THEN 'Canceled' 
   WHEN 4 THEN 'In progress' 
END AS Status,
CASE job.enabled
WHEN 0 THEN 'False' 
   WHEN 1 THEN 'True' 
END AS Enabled
FROM dbo.sysjobhistory hist
JOIN dbo.sysjobs_view job ON job.job_id=hist.job_id                    
WHERE job.[name] = '[Parallel] Copy DBOutboxMaster'  
OR job.[name] = '[Parallel] Copy filestore to PPE' 
OR job.[name] = '[Parallel] copyLogShippingForECW' 
OR job.[name] = '[Parallel] copyLogShippingForNLASQL'
GROUP BY job.name,hist.run_date,hist.run_time,hist.run_status,job.enabled
ORDER BY lastrun DESC

我目前得到了结果:

[Parallel] Copy DBOutboxMaster  2017-10-20 09:32:00.000 Success True
[Parallel] Copy filestore to PPE    2017-10-20 09:32:00.000 Success True
[Parallel] copyLogShippingForECW    2017-10-20 09:32:00.000 Success True
[Parallel] copyLogShippingForNLASQL 2017-10-20 09:31:11.000 Success True
[Parallel] Copy DBOutboxMaster  2017-10-20 09:31:00.000 Success True

正如您所看到的,每个作业都有重复的字段。我只想要每个职位的最高记录,所以总共应该只有4个最新LastRun日期时间的结果

3 个答案:

答案 0 :(得分:0)

感谢George Menoutis,对此的回答是在以下查询中,通过对运行日期和状态字段进行分组:

SELECT 
job.Name,
MAX(CAST(CAST(hist.run_date AS CHAR(8))
+ ' ' 
+ STUFF(
STUFF(RIGHT('000000' + CAST(hist.run_time AS VARCHAR(6)),  6)
, 3, 0, ':')
, 6, 0, ':')
AS DATETIME)) AS LastRun,
MAX(CASE hist.run_status 
   WHEN 0 THEN 'Failed' 
   WHEN 1 THEN 'Success' 
   WHEN 2 THEN 'Retry' 
   WHEN 3 THEN 'Canceled' 
   WHEN 4 THEN 'In progress' 
END) AS STATUS,
CASE job.enabled
WHEN 0 THEN 'False' 
   WHEN 1 THEN 'True' 
END AS Enabled
FROM dbo.sysjobhistory hist
JOIN dbo.sysjobs_view job ON job.job_id=hist.job_id                    
WHERE job.[name] = '[Parallel] Copy DBOutboxMaster'  
OR job.[name] = '[Parallel] Copy filestore to PPE' 
OR job.[name] = '[Parallel] copyLogShippingForECW' 
OR job.[name] = '[Parallel] copyLogShippingForNLASQL'
GROUP BY job.name,job.enabled
ORDER BY lastrun DESC

结果:

[Parallel] Copy DBOutboxMaster  2017-10-20 09:43:00.000 Success True
[Parallel] Copy filestore to PPE    2017-10-20 09:43:00.000 Success True
[Parallel] copyLogShippingForECW    2017-10-20 09:32:00.000 Success True
[Parallel] copyLogShippingForNLASQL 2017-10-20 09:31:11.000 Success True

答案 1 :(得分:0)

使用TOP 1 WITH TIES + ROW_NUMBER

SELECT TOP 1 WITH TIES *
FROM (
    SELECT  job.[Name],
            CAST(CAST(hist.run_date AS CHAR(8))
            + ' ' 
            + STUFF(
            STUFF(RIGHT('000000' + CAST(hist.run_time AS VARCHAR(6)),  6)
            , 3, 0, ':')
            , 6, 0, ':')
            AS DATETIME) AS LastRun,
            CASE hist.run_status 
               WHEN 0 THEN 'Failed' 
               WHEN 1 THEN 'Success' 
               WHEN 2 THEN 'Retry' 
               WHEN 3 THEN 'Canceled' 
               WHEN 4 THEN 'In progress' 
            END AS Status,
            CASE job.enabled
            WHEN 0 THEN 'False' 
               WHEN 1 THEN 'True' 
            END AS Enabled
    FROM dbo.sysjobhistory hist
    JOIN dbo.sysjobs_view job ON job.job_id=hist.job_id                    
    WHERE  job.[name] = '[Parallel] Copy DBOutboxMaster'  
        OR job.[name] = '[Parallel] Copy filestore to PPE' 
        OR job.[name] = '[Parallel] copyLogShippingForECW' 
        OR job.[name] = '[Parallel] copyLogShippingForNLASQL'
    GROUP BY job.name,hist.run_date,hist.run_time,hist.run_status,job.enabled
) as t
ORDER BY ROW_NUMBER() OVER (PARTITION BY [Name] ORDER BY lastrun DESC)

答案 2 :(得分:0)

CROSS APPLY对“每行顶部(n)”要求很有用

SELECT
        job.Name
      , ca.LastRun
      , ca.Status
      , CASE job.enabled
                WHEN 0 THEN 'False'
                WHEN 1 THEN 'True'
        END AS Enabled
FROM dbo.sysjobs_view job 
CROSS APPLY (
        SELECT TOP(1)
                dateadd(day,datediff(day,0,run_date),cast(run_time as datetime)) AS LastRun
              , CASE hist.run_status
                        WHEN 0 THEN 'Failed'
                        WHEN 1 THEN 'Success'
                        WHEN 2 THEN 'Retry'
                        WHEN 3 THEN 'Canceled'
                        WHEN 4 THEN 'In progress'
                END AS Status
        FROM  dbo.sysjobhistory hist
        ORDER BY dateadd(day,datediff(day,0,run_date),cast(run_time as datetime)) DESC
        WHERE hist.job_id = job.job_id
        ) AS ca
WHERE job.[name] = '[Parallel] Copy DBOutboxMaster'
OR job.[name] = '[Parallel] Copy filestore to PPE'
OR job.[name] = '[Parallel] copyLogShippingForECW'
OR job.[name] = '[Parallel] copyLogShippingForNLASQL'
ORDER BY ca.LastRun DESC
;

修改

添加类型为date&的单独列。时间在一起,一个简单/快速的方法是计算从零日期开始的天数,然后在将时间值转换为datetime之后将其添加到时间。

dateadd(day,  datediff(day,0,run_date)  ,cast(run_time as datetime))

使用基于数字的日期函数意味着您不依赖于服务器设置来将字符串解释为日期,并且它们比转换为字符串/从字符串转换更快。