0

毎秒行を受信して​​いるテーブルがあり、毎秒アクティビティの状態がタイムスタンプと共に配信されます。たとえば、状態が 6 から 0 になり、状態が再び変化するまですべて 0 になる場合など、状態の特定の変化に基づいてグループ化する必要があります。この質問を説明する最良の方法は、次の例です。

|タイムスタンプ | 状態|

|13:05:00 | 1 |
|13:05:05 | 0 |
|13:05:10 | 0 |
|13:05:15 | 6 |
|13:05:20 | 6 |
|13:05:25 | 0 |
|13:05:30 | 0 |
|13:05:35 | 6 |
|13:05:40 | 6 |
|13:05:45 | 0 |
|13:05:50 | 0 |

このテーブルから取得できるようにしたい結果は、2 つのグループ (6 から 0 への状態の 2 つの変化があります) であり、状態が再び変化するまで、6 の状態に続くすべての 0 の状態をグループ化します。<13:05:25,13:05:30>;<13:05:45,13:05:50>

4

2 に答える 2

1
    CREATE TABLE MyTable
    (
      [TimeStamp] NVARCHAR(10),
      [State] INT
    )

    INSERT INTO MyTable ([TimeStamp], [State])
    SELECT '13:05:00', 1
    UNION ALL
    SELECT '13:05:05', 0
    UNION ALL
    SELECT '13:05:10', 0
    UNION ALL
    SELECT '13:05:15', 6
    UNION ALL
    SELECT '13:05:20', 6
    UNION ALL
    SELECT '13:05:25', 0
    UNION ALL
    SELECT '13:05:30', 0
    UNION ALL
    SELECT '13:05:35', 6
    UNION ALL
    SELECT '13:05:40', 6
    UNION ALL
    SELECT '13:05:45', 0
    UNION ALL
    SELECT '13:05:50', 0
    GO

;WITH cte( [RowNum], [TimeStamp], [State]) AS
(
  SELECT ROW_NUMBER() OVER(ORDER BY TIMESTAMP), TIMESTAMP, STATE FROM MyTable
)
SELECT 
t2.TimeStamp AS [Start],
ISNULL
(
  (SELECT TimeStamp FROM cte WHERE RowNum = (SELECT TOP 1 RowNum FROM cte WHERE State <> 0 AND RowNum > t2.RowNum ORDER BY TimeStamp)-1)
  ,(SELECT MAX(TimeStamp) FROM cte)
) [End]
FROM cte t1
JOIN cte t2 ON t1.RowNum = t2.RowNum - 1
WHERE t1.State = 6 AND t2.State = 0
GO

またはフィドルで試してください

于 2013-07-08T12:04:19.100 に答える
0

質問が十分に明確かどうかわかりません:| 6 から 0 への最初の変更を見つけるのは簡単だったので、別の方法でアプローチしました。

with x as (
  select *, rn = ROW_NUMBER() OVER (ORDER BY Activity_Time)
  FROM WellData_Activity
  )
  Select x.Activity_Code, x.Activity_Time
  from x left outer join x as y
  on x.rn = y.rn + 1
  and x.Activity_Code <> y.Activity_Code
  where y.activity_code is not null

しかし、一連の activity_code のグループ化を同時に行うのはより困難だったので、これを使用して最初にそれらを (時系列の activity_code で) グループ化し、次に最初のクエリを実行して行を返します (現在は始まりと終わり):

WITH periods AS (
SELECT
    *,
    grp = ROW_NUMBER() OVER (PARTITION BY Well_GUID        ORDER BY Activity_Time)
    - ROW_NUMBER() OVER (PARTITION BY Well_GUID, Activity_Code ORDER BY Activity_Time)
  FROM WellData_Activity
)
SELECT
  Well_GUID,
  date_from = MIN(Activity_Time),
  date_to   = MAX(Activity_Time),
  Activity_Code
FROM periods
GROUP BY
Well_GUID,
Activity_Code,
grp
ORDER BY
Well_GUID,
MIN(Activity_Time)
于 2013-07-08T12:02:54.277 に答える