9

あなたが私を助けてくれることを願っています。

HH_Solution_Audit テーブルのレコードを表示する必要があります -- 2 人以上のスタッフが 10 分以内に部屋に入った場合。要件は次のとおりです。

  1. タイムスタンプ (LAST_UPDATED) 間隔が 10 分以下のイベントのみを表示します。したがって、現在の行を次の行および前の行と比較して、DATEDIFF が 10 分以下かどうかを確認する必要があります。私はこの部分で終わりました。
  2. ルーム内で 10 分以内の個別の STAFF_GUID の数が 2 つ以上の場合、レコードのみを表示します。

HH_Solution_Audit テーブルの詳細:

  1. ID - PK
  2. STAFF_GUID - スタッフ ID
  3. LAST_UPDATED - スタッフが入室した日時

これが私がこれまでに得たものです。これは要件 1 のみを満たします。

CREATE TABLE HH_Solution_Audit (
ID INT PRIMARY KEY,
STAFF_GUID NVARCHAR(1),
LAST_UPDATED DATETIME
)
GO
INSERT INTO HH_Solution_Audit VALUES (1, 'b', '2013-04-25 9:01')
INSERT INTO HH_Solution_Audit VALUES (2, 'b', '2013-04-25 9:04')
INSERT INTO HH_Solution_Audit VALUES (3, 'b', '2013-04-25 9:13')
INSERT INTO HH_Solution_Audit VALUES (4, 'a', '2013-04-25 10:15')
INSERT INTO HH_Solution_Audit VALUES (5, 'a', '2013-04-25 10:30')
INSERT INTO HH_Solution_Audit VALUES (6, 'a', '2013-04-25 10:33')
INSERT INTO HH_Solution_Audit VALUES (7, 'a', '2013-04-25 10:41')
INSERT INTO HH_Solution_Audit VALUES (8, 'a', '2013-04-25 11:02')
INSERT INTO HH_Solution_Audit VALUES (9, 'a', '2013-04-25 11:30')
INSERT INTO HH_Solution_Audit VALUES (10, 'a', '2013-04-25 11:45')
INSERT INTO HH_Solution_Audit VALUES (11, 'a', '2013-04-25 11:46')
INSERT INTO HH_Solution_Audit VALUES (12, 'a', '2013-04-25 11:51')
INSERT INTO HH_Solution_Audit VALUES (13, 'a', '2013-04-25 12:24')
INSERT INTO HH_Solution_Audit VALUES (14, 'b', '2013-04-25 12:27')
INSERT INTO HH_Solution_Audit VALUES (15, 'b', '2013-04-25 13:35')

    DECLARE @numOfPeople INT = 2,   
              --minimum number of people that must be inside 
              --the room for @lengthOfStay minutes
            @lengthOfStay INT = 10, 
              --number of minutes of stay
            @dateFrom DATETIME = '04/25/2013 00:00',
            @dateTo DATETIME = '04/25/2013 23:59';
    WITH cteSource AS
    (
         SELECT ID, STAFF_GUID, LAST_UPDATED, 
              ROW_NUMBER() OVER (ORDER BY LAST_UPDATED) AS row_num
         FROM HH_SOLUTION_AUDIT 
              WHERE LAST_UPDATED >= @dateFrom AND LAST_UPDATED <= @dateTo
    )
    SELECT [current].ID, [current].STAFF_GUID, [current].LAST_UPDATED
    FROM
         cteSource AS [current]
    LEFT OUTER JOIN
         cteSource AS [previous] ON [current].row_num = [previous].row_num + 1
    LEFT OUTER JOIN
         cteSource AS [next] ON [current].row_num = [next].row_num - 1
    WHERE
         DATEDIFF(MINUTE, [previous].LAST_UPDATED, [current].LAST_UPDATED) 
         <= @lengthOfStay
         OR
         DATEDIFF(MINUTE, [current].LAST_UPDATED, [next].LAST_UPDATED) 
         <= @lengthOfStay  
    ORDER BY [current].ID, [current].LAST_UPDATED    

クエリを実行すると、次の ID が返されます: 1、2、3、5、6、7、10、11、12、13、14
これ
は、前の行、現在の行、および次の行。

2番目の要件について教えていただけますか?適用されている場合、返される ID は13、14のみです。

4

1 に答える 1

3

これがアイデアです。ROW_NUMBER と前後のレコードは必要ありません。結合されたクエリを実行するだけで済みます。1 つは誰かが X 分遅れてチェックしたすべての人を検索し、もう 1 つは X 分前もって検索します。それぞれが相関サブクエリと COUNT(*) を使用して、一致する人の数を見つけます。number が @numOfPeople より大きい場合は、それだけです。

編集:新バージョン: 10 分の前後で 2 つのクエリを実行する代わりに、10 分の遅れのみをチェックします - cteLastOnes で一致するものを選択します。その後、クエリの別の部分に移動して、10 分以内に実際に存在するものを検索します。最終的に再びそれらと「最後のもの」の結合を作る

WITH cteSource AS
(
    SELECT ID, STAFF_GUID, LAST_UPDATED
    FROM HH_SOLUTION_AUDIT 
    WHERE LAST_UPDATED >= @dateFrom AND LAST_UPDATED <= @dateTo
)
,cteLastOnes AS 
(
    SELECT * FROM cteSource c1
    WHERE @numOfPeople -1 <= (SELECT COUNT(DISTINCT STAFF_GUID) 
                              FROM cteSource c2 
                              WHERE DATEADD(MI,@lengthOfStay,c2.LAST_UPDATED) > c1.LAST_UPDATED 
                                AND C2.LAST_UPDATED <= C1.LAST_UPDATED 
                                AND c1.STAFF_GUID <> c2.STAFF_GUID) 
)
SELECT * FROM cteLastOnes
UNION
SELECT * FROM cteSource s
WHERE EXISTS (SELECT * FROM cteLastOnes l 
               WHERE DATEADD(MI,@lengthOfStay,s.LAST_UPDATED) > l.LAST_UPDATED 
                AND s.LAST_UPDATED <= l.LAST_UPDATED 
                AND s.STAFF_GUID <> l.STAFF_GUID)

SQLFiddle DEMO - 新バージョン

SQLFiddle DEMO - 古いバージョン

于 2013-08-14T15:07:03.470 に答える