2

WorkflowId グループごとに、プロセス コード 10 の前にプロセス コード 20 が LastModifiedTime を持っている回数をカウントしたいと思います。

このクエリは、テーブル レイアウトといくつかのデータを示しています。

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

ここに画像の説明を入力

いろいろやってみたのですが、なかなかうまくいきません。それぞれの試みは、ここに投稿する価値のない行き止まりにつながりました. 20 が 10 の前に来る回数をすべて確認する方法はありますか? そして、それらの間の時差を見ることさえありますか?

4

4 に答える 4

2

グループ内に複数の 10 がある場合、レビュー時にこれは中断されます

1 つのグループが 10 人を超えることはありますか? その場合、どのように処理しますか?

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

--ボブ・ホーンから編集--

上記のクエリを少し変更して、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
于 2012-09-27T17:03:15.990 に答える
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 ごとに 2 つの異なるランキングを取得しています。プロセス コードが正しい (つまり、昇順の) 順序である場合、両方のランキングは同じであるため、差は 0 になります。そうでない場合、ランキングは異なり、それらの差はゼロではありません。

于 2012-09-27T17:35:01.177 に答える
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
   )

これにより、順不同のワークフローごとに 1 行が返されるため、 のSELECT Count(*)代わりに簡単に変更できますSELECT *

EventTime も重要になった場合は、それを exists 句に OR として LastModifiedTime と一緒に追加することもできます。

それらの間の時間差が必要であることに気付きました(行ごとに詳細を表示すると、単一のカウントを返すことができないことを意味します)。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
于 2012-09-27T17:41:37.503 に答える
1

クエリに行番号を追加して、それを SELECT WHERE PROCESSCODE=20 AND (SELECT PROCESSCODE FROM [同じクエリ] WHERE 行番号=行番号+1)=10 内にラップできると思います。またはそのようなもの。詳細は解っていません。

于 2012-09-27T17:04:38.083 に答える