MySQLでは、データの取得中にSELECTステートメントで変数を割り当てることができます。この機能は、ウィンドウ関数(MySQLにはない)を「通常」使用する多くの問題を解決するのに役立ちます。それはあなたにも役立ちます。これが私が最終的に得た解決策です:
SET @startdate = CAST(NULL AS datetime);
SET @granularity = 60; /* minutes */
SET @minduration = 180; /* minutes */
SET @minvalue = 10;
SELECT
t.Date,
t.Value
FROM (
SELECT
StartDate,
MAX(Date) AS EndDate
FROM (
SELECT
Date,
Value,
CASE
WHEN Value > @minvalue OR @startdate IS NOT NULL
THEN IFNULL(@startdate, Date)
END AS StartDate,
@startdate := CASE
WHEN Value > @minvalue
THEN IFNULL(@startdate, Date)
END AS s
FROM (
SELECT Date, Value FROM YourTable
UNION ALL
SELECT MAX(Date) + INTERVAL @granularity MINUTE, @minvalue FROM YourTable
) s
ORDER BY Date
) s
WHERE StartDate IS NOT NULL
GROUP BY StartDate
) s
INNER JOIN YourTable t ON t.Date >= s.StartDate AND t.Date < s.EndDate
WHERE s.EndDate >= s.StartDate + INTERVAL @minduration MINUTE
;
ここで使用されている4つの変数のうち3つは単なるスクリプト引数であり@startdate
、実際に割り当てられてクエリでチェックされるのは1つだけです。
基本的に、クエリは行を繰り返し処理し、値が特定の最小値()より大きい行をマークして@minvalue
、最終的に値が条件に一致する時間範囲のリストを生成します。実際には、終了境界を正しく計算するために、一致する行のグループの直後に続く一致しない行もそれぞれのグループに含まれます。そのため、元のデータセットに追加の行が追加されています。この行はDate
、最新のデータセットにDate
加えて、テーブル内の指定され@granularity
たタイムスタンプから計算され、はだけValue
です@minvalue
。
取得されると、範囲のリストが元のテーブルに結合され、範囲の境界の間にある詳細行が取得されます。範囲の長さが十分でない(で指定されて@minduration
いる)範囲は、途中で除外されます。
このソリューションをSQLFiddleで実行すると、次の出力が表示されます。
DATE VALUE
------------------------------ -----
January, 01 2000 03:00:00-0800 11
January, 01 2000 04:00:00-0800 11
January, 01 2000 05:00:00-0800 11
これは、あなたが期待することだと私は理解しています。