1

id、date datetime、value doubleのテーブルを考えてみましょう。テーブルには、毎分データがあります。

mysqlを使用して、値が10を超える「イベント」を3時間以上継続して識別しようとしています。

クエリを使用しているとき:

select date from table where value > 10;

次に、日付が連続している場所を手動で読みました。

「イベント」の例:

Date             - value
2000/01/01 00:00 - 5
2000/01/01 01:00 - 5
2000/01/01 02:00 - 5
2000/01/01 03:00 - 11
2000/01/01 04:00 - 11
2000/01/01 05:00 - 11
2000/01/01 06:00 - 5
2000/01/01 07:00 - 5
2000/01/01 08:00 - 5
2000/01/01 09:00 - 11
2000/01/01 10:00 - 11
2000/01/01 11:00 - 5

この場合、03:00から05:00の間に1つの「イベント」があります。

4

3 に答える 3

2

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

これは、あなたが期待することだと私は理解しています。

于 2012-05-16T18:21:00.873 に答える
0
select count(*) from table where DATE_SUB(CURDATE(),INTERVAL 3 HOUR) < `date`

select count(*) from table where DATE_SUB(CURDATE(),INTERVAL 3 HOUR) < `date` AND `value` > 10

次に、結果を比較します。同じでない場合は、継続的ではありません。

于 2012-05-16T08:50:53.603 に答える
0

当てずっぽう:

select * from 
    (select event, MAX(date) as date from table where value > 10 group by event) maxs
inner join 
    (select event, MIN(date) as date from table where value > 10 group by event) mins
on maxs.event = mins.event
where (time_to_sec(timediff(maxes.date, mins.date)) / 3600) > 3
于 2012-05-16T08:51:35.323 に答える