2017-12-18 9 views
0

私はストアドプロシージャでフィルタリングする必要がある何百万ものログを持つSQL Server 2016のテーブルを持っています。各ログには、このフィルタリングに使用するLogTimeフィールドがあります。私はLogTimeで互いに近すぎるものをスキップして、15分以上離れたログだけを返したいと思います。DateTime間隔によるSQL行のフィルタリング

一般に、ログは互いに秒以内であるため、この時間間隔によってログが適切に制限されます。また、ほとんどのログ項目をスキップしても構いません。また、間隔が少なくとも15分である限り、次のログが数時間離れている場合、ログ間の間隔が15分を超えるかどうかは関係ありません。

たとえば、最初のログは15:30に、15:45まですべてのログをスキップします。次のログを15:46に見つけて、そのように実行してください。私は必要な出力の

例:

15:30 - Log Content 
15:46 - Log Content 
16:12 - Log Content 
18:00 - Log Content 

私は試行錯誤のもののすべての種類を検索し、しようとしてきました。残念ながら、私のSQL知識はそれほど広がらず、まともな時間枠で実行されるソリューションを作成することができませんでした。

+0

私たちは問題に対する満足のいくSQLソリューションを見つけることができませんでしたので、次のチャンクを要求する前に、DBへリクエストをチャンクし、サーバーでフィルタリングする組み合わせ戦略を使用しました。 – Iyashu5040

答えて

0

WITH CTE 
AS 
(
    SELECT 
     SeqNo = 1, 
     LogTime = MIN(LogTime) 
     FROM LogTable 

    UNION ALL 

    SELECT 
     SeqNo = SeqNo+1, 
     LogTime = DATEADD(MINUTE,15,LogTime) 
     FROM CTE 
      WHERE LogTime < GETDATE() 
      OR SeqNo < 100 
) 
SELECT 
    * 
    FROM LogTable LT 
     WHERE EXISTS 
     (
      SELECT 1 FROM CTE WHERE LogTime = LT.LogTime 
     ) 

これは、ログテーブルの開始から15分の間隔ですべてのレコードを表示します。 100個の異なるタイムスロットまたは現在の時刻までの現在時刻。これは最初の時刻です。

0

これはコメントには長すぎます。

問題を説明したように、非常に計算コストが高くなります。再帰的なCTEまたはカーソルを使用して解決できます。いずれの方法でも時間がかかります。

2つの選択肢があります。 1つは、各日付/時刻を15分間隔で切り捨て、最初の日付/時刻を引き出すことです。あなたは使ってこれを行うことができます。

select t.* 
from (select t.*, 
      row_number() over (partition by cast(logtime as date), datepart(hour, logtime), datepart(minute, logtime)/4 
           order by logtime) as seqnum 
     from t 
    ) t 
where seqnum = 1; 

別の方法は、15分以上のギャップがあるときにシーケンスの最初を取ることです。このため、lag()を使用します。

select t.* 
from (select t.*, lag(logtime) over (order by logtime) as prev_logtime 
     from t 
    ) t 
where logtime > dateadd(minute, 15, prev_logtime) or prev_logtime is null; 
0

それを行うための簡単な方法は、各レコードの前の時間を取得し、それらの間の分の数を計算し、このようになりますクエリを使用することです。

SELECT * FROM YourTable 
WHERE DateDiff(mi, (SELECT TOP 1 LogTime FROM YourTable as sub 
    WHERE YourTable.LogTime > sub.LogTime ORDER BY LogTime DESC), LogTime) > 15