的問題是日數據中如下放入status_table(這可高達每天彙總數據
4000項期間,我希望把數據放到一個更有條理的夜晚在存儲表 (status_table_storage)中,並將其從status_table中刪除 這個想法是將所有狀態相同的條目分組,直到狀態/錯誤發生變化爲止,新組應該開始被放入表可以在小提琴中找到一個例子
做這件事的最好方法是什麼
表結構的一個例子可以在這裏找到:http://sqlfiddle.com/#!9/488524/1
的問題是日數據中如下放入status_table(這可高達每天彙總數據
4000項期間,我希望把數據放到一個更有條理的夜晚在存儲表 (status_table_storage)中,並將其從status_table中刪除 這個想法是將所有狀態相同的條目分組,直到狀態/錯誤發生變化爲止,新組應該開始被放入表可以在小提琴中找到一個例子
做這件事的最好方法是什麼
表結構的一個例子可以在這裏找到:http://sqlfiddle.com/#!9/488524/1
一步一步的解釋:
首先,你的名字和時間戳訂購表,並初始化3 user-defined variables。
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值時,它的第一行,被讀取。然後將當前行的值分配給變量。所以我們可以將當前行與前一行進行比較。如果事情發生了變化,我們只需遞增第三個變量,這是我們正在構建的每個「組」的數字。
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
感謝您的很好的解釋 –
不客氣工作。 – fancyPants