【问题标题】:Doing Counts based on timestamps根据时间戳进行计数
【发布时间】:2016-08-07 22:15:11
【问题描述】:

我有一个查询给我以下结果。此结果集包含服务器上作业的启动时间和完成时间。

JobName             LatestStartTime         LatestEndTime
Job1                2016-04-15 00:00:40.000 2016-04-15 00:07:40.000
Job2                2016-04-15 00:01:23.000 2016-04-15 00:17:37.000
Job3                2016-04-15 08:00:03.000 2016-04-15 08:18:05.000
Job4                2016-04-15 08:30:06.000 2016-04-15 08:57:21.000
Job5                2016-04-15 09:00:03.000 2016-04-15 09:07:49.000
Job6                2016-04-15 03:53:40.000 2016-04-15 03:53:41.000
Job7                2016-04-15 09:30:07.000 2016-04-15 11:36:35.000

另一方面,我有一个查询,它创建一个间隔为 15 分钟的临时表。如下:

Increment
2016-04-15 00:00:00.000
2016-04-15 00:15:00.000
2016-04-15 00:30:00.000
2016-04-15 00:45:00.000
2016-04-15 01:00:00.000
2016-04-15 01:15:00.000
2016-04-15 01:30:00.000
2016-04-15 01:45:00.000
2016-04-15 02:00:00.000
2016-04-15 02:15:00.000
2016-04-15 02:30:00.000
2016-04-15 02:45:00.000

我想知道哪些作业以确定的增量运行。例如,我的最终结果集应该类似于:

Increment                     NumberOfJobs    JobNames
2016-04-15 00:00:00.000       2               Job1, Job2
2016-04-15 00:15:00.000       1               Job2
2016-04-15 00:30:00.000       0               NULL

Increment                     NumberOfJobs    JobNames
2016-04-15 00:00:00.000       2               Job1
2016-04-15 00:00:00.000       2               Job2

2016-04-15 00:15:00.000       1               Job2
2016-04-15 00:30:00.000       0               NULL

【问题讨论】:

    标签: sql sql-server timestamp


    【解决方案1】:

    困难的部分是在一行中获取作业列表。计数很简单:

    select t.increment, j.jobname,
           sum(count(*)) over (partition by t.increment) as countOfJobs
    from times t left join
         jobs j
         on t.increment >= j.lasteststarttime and
            t.increment <= j.lastestendtime
    group by t.increment, j.jobname
    order by increment, jobname;
    

    获取列表需要 SQL Server 中的一个奇怪的子查询:

    select t.increment, count(*) as numJobs,
           stuff((select ', ' + j2.jobname
                  from jobs j2
                  where t.increment >= j2.lasteststarttime and
                        t.increment <= j2.lastestendtime
                  for xml path ('')
                 ), 1, 1, '') as jobs
    from times t  left join
             jobs j
             on t.increment >= j.lasteststarttime and
                t.increment <= j.lastestendtime
    group by t.increment
    order by increment;
    

    如果作业名称包含不寻常的字符(那些需要为 XML 转义的字符),那么 XML 逻辑会稍微复杂一些。不过,对于职位名称来说,这似乎不太可能。

    【讨论】:

    • 你得到错误的结果,在间隔之后得到正确的工作你需要SELECT Max([increment]) AS t FROM temp_table WHERE [increment] &lt; q.LatestStartTime
    • 谢谢!这个查询正好符合我的要求!
    【解决方案2】:

    试试这个:

    SELECT [increment], JobName
    , Count(1) over (Partition by [increment]) AS NumberOfJobs    
    FROM temp_table
    INNER JOIN (
      SELECT JobName, st.t AS t1, LatestEndTime AS t2
      FROM query AS q
      OUTER APPLY (
        SELECT Max([increment]) AS t 
        FROM temp_table 
        WHERE [increment] < q.LatestStartTime) as st
      ) as j ON Increment BETWEEN j.t1 and j.t2
    

    它返回:

    increment   JobName NumberOfJobs
    2016-04-15 00:00:00.000 Job1    2
    2016-04-15 00:00:00.000 Job2    2
    2016-04-15 00:15:00.000 Job2    1
    2016-04-15 02:45:00.000 Job3    5
    2016-04-15 02:45:00.000 Job4    5
    2016-04-15 02:45:00.000 Job5    5
    2016-04-15 02:45:00.000 Job6    5
    2016-04-15 02:45:00.000 Job7    5
    

    左连接:

    SELECT [increment], JobName
    , Count(JobName) over (Partition by [increment]) AS NumberOfJobs    
    FROM temp_table
    LEFT JOIN (
      SELECT JobName, st.t AS t1, LatestEndTime AS t2
      FROM query AS q
      OUTER APPLY (
        SELECT Max([increment]) AS t 
        FROM temp_table 
        WHERE [increment] < q.LatestStartTime) as st
      ) as j ON Increment BETWEEN j.t1 and j.t2
    

    返回:

    2016-04-15 00:00:00.000 Job1    2
    2016-04-15 00:00:00.000 Job2    2
    2016-04-15 00:15:00.000 Job2    1
    2016-04-15 00:30:00.000 NULL    0
    2016-04-15 00:45:00.000 NULL    0
    2016-04-15 01:00:00.000 NULL    0
    2016-04-15 01:15:00.000 NULL    0
    2016-04-15 01:30:00.000 NULL    0
    2016-04-15 01:45:00.000 NULL    0
    2016-04-15 02:00:00.000 NULL    0
    2016-04-15 02:15:00.000 NULL    0
    2016-04-15 02:30:00.000 NULL    0
    2016-04-15 02:45:00.000 Job3    5
    2016-04-15 02:45:00.000 Job4    5
    2016-04-15 02:45:00.000 Job5    5
    2016-04-15 02:45:00.000 Job6    5
    2016-04-15 02:45:00.000 Job7    5
    

    【讨论】:

      【解决方案3】:
      SELECT  *,
              COUNT(*) OVER (PARTITION BY increment) numberOfJobs
      FROM    times
      JOIN    jobs
      ON      increment BETWEEN latestStartTime AND latestEndTime
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-07
        • 1970-01-01
        • 2015-02-01
        • 1970-01-01
        • 2020-04-15
        • 2015-06-25
        • 1970-01-01
        相关资源
        最近更新 更多