ステップバイステップの説明:
まず、テーブルを名前とタイムスタンプで並べ替え、3つのユーザーを初期化します。 -定義された変数 。
SELECT s.* FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp
ご覧のとおり、そのためにサブクエリを使用できます。 ORDER BY
リレーショナルデータベースには、指定しない限り順序がないため、重要です。
ここで、MySQLはSELECT
を評価します 指定された順序で句を使用するため、ここで順序を変更しないでください。
SELECT
s.*,
@prevName,
@prevStatus,
@prevName := s.name,
@prevStatus := s.status
FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp
このステートメントを実行すると、変数を選択するだけで前の行の値を保持するか、最初の行が読み取られたときにNULLを保持することがわかります。次に、現在の行の値が変数に割り当てられます。これで、現在の行を前の行と比較できます。何かが変更された場合は、3番目の変数をインクリメントするだけです。これは、構築している各「グループ」の数値です。
SELECT
s.*,
@group_number := IF(@prevName != s.name OR @prevStatus != s.status, @group_number + 1, @group_number) AS group_number,
@prevName := s.name,
@prevStatus := s.status
FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp
そこで、@group_number
をインクリメントしました 何かが変更され、変更されていない場合は変数がそれ自体に割り当てられ、変更されない場合。
これで、このクエリをサブクエリとして使用して、簡単なグループ化を行うことができます。
SELECT
group_number AS id,
name,
status,
MIN(error) AS error,
MIN(timestamp) AS firstEntry,
MAX(timestamp) AS lastEntry,
COUNT(*) AS entries
FROM (
SELECT
s.*,
@group_number := IF(@prevName != s.name OR @prevStatus != s.status, @group_number + 1, @group_number) AS group_number,
@prevName := s.name,
@prevStatus := s.status
FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp
) sq
GROUP BY
group_number,
name,
status
- この
sqlfiddle で機能することを確認してください