显示时差无序

时间:2012-09-27 16:53:31

标签: sql sql-server tsql

我想知道每个WorkflowId分组的流程代码为10之前,20的流程代码有多少次具有LastModifiedTime。

此查询显示表格布局和一些数据:

SELECT TOP 10 * 
FROM master.ProcessLogging with (nolock) 
WHERE ProcessCode = 10 OR ProcessCode = 20 
ORDER BY WorkflowId, ProcessCode

enter image description here

我尝试了一些事情,但是我很难将它付诸实践。每次尝试都会导致死胡同,这里不值得发布。有没有办法看到20在10之前的所有时间?甚至可能看到它们之间的时差?

4 个答案:

答案 0 :(得分:2)

一旦审查,如果一组中超过10个

,这将会中断

组中是否会有超过10个,如果是这样,您希望如何处理它?<​​/ p>

SELECT p10.WorkflowId, count(p20.WorkflowId)
FROM master.ProcessLogging p10 
left outer join master.ProcessLogging p20
  on  p20.WorkflowId = p10.WorkflowId
  and p20.EventTime < p10.EventTime
  and p20.ProcessCode = 20
where p10.ProcessCode = 10 
group by p10.WorkflowId 
order by p10.WorkflowId

- 从Bob Horn编辑 -

略微修改上面的查询以显示10和20之间的最大时差。

SELECT p10.WorkflowId, min(p20.WorkflowId), 
       DATEDIFF(ms, min(p10.lastmodifiedtime), min(p20.lastmodifiedtime)) as 'Diff (ms)'
FROM master.ProcessLogging p10 
join master.ProcessLogging p20
  on  p20.WorkflowId = p10.WorkflowId
  and p20.EventTime < p10.EventTime
  and p20.ProcessCode = 20
where p10.ProcessCode = 10 
group by p10.WorkflowId 
order by ABS(DATEDIFF(ms, min(p10.lastmodifiedtime), min(p20.lastmodifiedtime))) DESC

答案 1 :(得分:1)

我想你可以在你的查询中添加row number,然后将它包装在SELECT WHERE PROCESSCODE = 20 AND(SELECT PROCESSCODE FROM [same query] WHERE rownumber = rownumber + 1)= 10中。或类似的东西。没有弄清楚细节。

答案 2 :(得分:1)

这应该这样做

with cte as (
    SELECT *,
        row_number() over (partition by WorkflowId order by ProcessCode) as [a] ,
        row_number() over (partition by WorkflowId order by LastModifiedTime) as [b]
    FROM master.ProcessLogging with (nolock) 
    WHERE ProcessCode = 10 OR ProcessCode = 20 
)
select * from cte
where [a] - [b] <> 0

作为解释,我为每个WorkflowId获得两个不同的排名。如果过程代码是正确的(即升序)顺序,那么两个排名将是相同的,因此差异将为0.如果不是,排名将是不同的,并且它们的差异将是非零。

答案 3 :(得分:1)

如果基于LastModifiedTime,每个WorkflowId总是应该是20,那么它非常简单。您甚至不必查看EventTime。不需要Row_Number:

SELECT *
FROM
   master.ProcessLogging L
WHERE
   L.ProcessCode = 20
   AND EXISTS (
      SELECT *
      FROM master.ProcessLogging L2
      WHERE
         L.WorkflowId = L2.WorkflowId
         AND L.LastModifiedTime < L2.LastModifiedTime
         AND L2.ProcessCode = 10
   )

这将为每个无序工作流程返回一行,因此您可以轻松将其更改为SELECT Count(*)而不是SELECT *

如果EventTime也变得很重要,你也可以将它作为OR与LastModifiedTime一起添加到exists子句中。

我刚注意到你想要它们之间的时差(通过显示每行的细节意味着你不能返回一个计数)。这是一个可以在SQL 2005及更高版本中执行此操作的查询。如果您使用的内容少于SQL Server 2005,请告诉我们,我会给您写一个不同的查询。

SELECT
   *,
   MinutesApart = DateDiff(minute, L.LastModifiedTime, L2.LastModifiedTime)
FROM
   master.ProcessLogging L
   CROSS APPLY (
      SELECT TOP 1 *
      FROM master.ProcessLogging L2
      WHERE
         L.WorkflowId = L2.WorkflowId
         AND L.LastModifiedTime < L2.LastModifiedTime
         AND L2.ProcessCode = 10
      ORDER BY L2.LastModifiedTime DESC
   ) L2
WHERE
   L.ProcessCode = 20

请注意,如果您在20之后有多个10个代码,则只显示最差的代码。要查看所有这些(并且每20个代码获得多行),您可以将其更改为简单的自联接:

SELECT
   *,
   MinutesApart = DateDiff(minute, L.LastModifiedTime, L2.LastModifiedTime)
FROM
   master.ProcessLogging L
   INNER JOIN master.ProcessLogging L2
      ON L.WorkflowId = L2.WorkflowId
WHERE
   L.ProcessCode = 20
   AND L2.ProcessCode = 10
   AND L.LastModifiedTime < L2.LastModifiedTime