Penjelasan langkah demi langkah:
Pertama, Anda memesan tabel berdasarkan nama dan stempel waktu dan menginisialisasi tiga pengguna -variabel yang ditentukan .
SELECT s.* FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp
Seperti yang Anda lihat, kita dapat menggunakan subquery untuk itu. ORDER BY
penting, karena tidak ada urutan dalam database relasional, kecuali jika Anda menentukannya.
Sekarang, MySQL mengevaluasi SELECT
klausa dalam urutan yang ditentukan, oleh karena itu jangan ubah urutannya di sini.
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
Saat Anda menjalankan pernyataan ini, Anda dapat melihat, bahwa ketika kita cukup memilih variabel yang memiliki nilai dari baris sebelumnya atau NULL ketika itu adalah baris pertama, yang dibaca. Kemudian nilai baris saat ini ditugaskan ke variabel. Jadi kita bisa membandingkan sekarang baris saat ini dengan baris sebelumnya. Jika ada yang berubah, kita cukup menaikkan variabel ketiga, yang merupakan angka untuk setiap "grup" yang kita bangun.
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
Jadi kami menambahkan @group_number
ketika sesuatu berubah dan menetapkan variabel untuk dirinya sendiri jika tidak, sehingga tidak berubah.
Sekarang kita cukup menggunakan kueri ini sebagai subkueri dan melakukan pengelompokan sederhana.
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
- lihat ini bekerja di sqlfiddle ini