0

私のギャップ検出は、時間差として設定したものをすべて拾い上げ、それに基づいて間隔ごとに実行しているようです。

だからここに私のデータ構造と私が何を求めているかの説明があります:

次のように設定されたデータベースがあります。

(Schema Name)
Historical
     -CID      int UQ AI NN 
     -ID       Int PK
     -Location Varchar(255)
     -Status   Varchar(255)
     -Time     datetime

私のデータは次のようになります (例: 選択した ID の 5 行)

 433275 | 97  | MyLocation | OK | 2013-08-20 13:05:54
 433275 | 97  | MyLocation | OK | 2013-08-20 13:00:54
 433275 | 97  | MyLocation | OK | 2013-08-20 12:25:54
 433275 | 97  | MyLocation | OK | 2013-08-20 12:20:54
 433275 | 97  | MyLocation | OK | 2013-08-20 12:15:54

上記の場合、ID 97 の 12:25:54 -> 13:00 のデータが欠落していることに気付くでしょう。次のことを知らせるレポートを作成しようとしています: ダウンタイムの開始、ダウンタイムの期間、ダウンタイムの終わり

これが私のコードです(php -> mysql)(動作していません)。

        select *from (
            SELECT
            y.*,
            TIMESTAMPDIFF(MINUTE, @prevDT, `Time`) AS timedifference,
            @prevDT := `Time`
            FROM ddHistorical y,
            (SELECT @prevDT:=(SELECT MIN(`Time`) FROM ddHistorical)) vars
            Where ID  = '". mysql_real_escape_string($ID)."'
            HAVING timedifference > 16
          ) s
          order by Time desc
          Limit 25";
4

2 に答える 2

1

次の 2 つのレベルのサブクエリが必要です。

SELECT *
FROM (
    SELECT  y.*,
            TIMESTAMPDIFF(MINUTE, @prevDT, `Time`) AS timedifference,
            @prevDT := `Time`
            FROM (SELECT *
                  FROM ddHistorical
                  WHERE ID = '97'
                  ORDER BY `Time`) y,
                 (SELECT @prevDT:=(SELECT MIN(`Time`) FROM ddHistorical)) vars) z
WHERE timedifference > 16
LIMIT 25

なぜ最も外側のレベルが必要なのか、実際にはわかりません。私はそれなしで(つまり、で始まるSELECT y.*)とを使用してみHAVING timedifference > 16ました。何らかの理由で、これはtimedifference = 45. しかし、そのHAVING句を削除すると、すべての行が表示され、ギャップは 35 分と報告されました。通常、両者の間に違いはありません

SELECT ... HAVING <cond>

SELECT * FROM (SELECT ...) WHERE <cond>

このクエリがルールに違反している理由はわかりません。ユーザー変数に関係があると思われます。

編集:

でうまくいかなかった理由がわかったと思いますHAVING。MySQL は、各行のtimedifference列を計算するとすぐにその条件を評価し、行を破棄しているようです。の場合、句timedifference <= 16の残りの列を計算する必要がないため、決して実行しません。したがって、その条件を超えるまでは、常に と比較しています。SELECT@prevDT := TimeMIN(Time)

チェックを外側のクエリに移動するtimedifferenceと、フィルタリングする前にすべての違いを計算するように強制されます。

SQLFIDDLE

于 2013-08-24T00:46:08.737 に答える
0

これを試してください:

"
SELECT y.*,
       TIMESTAMPDIFF(MINUTE, y.prevDT, y.`Time`) AS timedifference
  FROM (SELECT w.*, (SELECT MAX(x.`Time`)
                       FROM ddHistorical x
                      WHERE x.ID = w.ID
                        AND x.`Time` < w.`Time`) AS prevDT
          FROM ddHistorical w
         WHERE w.ID  = '". mysql_real_escape_string($ID)."') y
 WHERE TIMESTAMPDIFF(MINUTE, y.prevDT, y.`Time`) > 16
 ORDER BY y.`Time` DESC
 LIMIT 25";
于 2013-08-24T01:51:59.317 に答える