Giải thích từng bước:
Đầu tiên, bạn sắp xếp bảng theo tên và dấu thời gian và khởi tạo ba người dùng -các biến được xác định .
SELECT s.* FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp
Như bạn có thể thấy, chúng tôi có thể sử dụng một truy vấn con cho điều đó. ORDER BY
rất quan trọng, vì không có thứ tự nào trong cơ sở dữ liệu quan hệ, trừ khi bạn chỉ định nó.
Bây giờ, MySQL đánh giá SELECT
mệnh đề theo thứ tự được chỉ định, do đó không thay đổi thứ tự ở đây.
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
Khi thực hiện câu lệnh này, bạn có thể thấy rằng khi chúng ta chỉ cần chọn các biến mà chúng giữ giá trị của hàng trước đó hoặc NULL khi đó là hàng đầu tiên, đã được đọc. Sau đó, giá trị của hàng hiện tại được gán cho các biến. Vì vậy, chúng ta có thể so sánh hàng hiện tại với hàng trước đó. Nếu có điều gì đó thay đổi, chúng tôi chỉ cần tăng biến thứ ba, là một số cho mỗi "nhóm" mà chúng tôi đang xây dựng.
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
Vì vậy, chúng tôi đã tăng @group_number
khi một cái gì đó thay đổi và chỉ định biến cho chính nó nếu không, để nó không thay đổi.
Giờ đây, chúng ta có thể chỉ cần sử dụng truy vấn này làm truy vấn con và thực hiện một nhóm đơn giản.
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
- thấy nó hoạt động trong sqlfiddle này