2012-08-24 30 views
3

我有一個存儲具有兩個屬性的項目的表。因此,該表有三列:如何查詢MySQL中列中的更改數

item_id | property_1 | property_2 | insert_time 
    1  | 10   | 100   | 2012-08-24 00:00:01 
    1  | 11   | 100   | 2012-08-24 00:00:02 
    1  | 11   | 101   | 2012-08-24 00:00:03 
    2  | 20   | 200   | 2012-08-24 00:00:04 
    2  | 20   | 201   | 2012-08-24 00:00:05 
    2  | 20   | 200   | 2012-08-24 00:00:06 

也就是說,任何項目的變化,每次要麼屬性,一個新的行插入。還有一個存儲插入時間的列。現在我想要獲得property_2中的更改次數。對於上表,我應該得到

item_id | changes_in_property_2 
1  | 2 
2  | 3 

我該如何得到這個?

+0

你在表格上有一個id列,或者每個記錄有一個datetime字段嗎?只是好奇,否則有沒有辦法對記錄進行排序? – Tom

+1

考慮到示例數據中第4行和第6行之間沒有差異,您將會遇到問題。您可能需要添加某種可排序的按時間順序排列的信息以允許來回遍歷,以便比較上一個值和下一個值。 – ahillman3

+0

由於第4行和第6行是相同的,所以很難確定變化。您需要另一列或不同的錄製方法。 – Kermit

回答

0

這會告訴你輸入了多少個不同的值。如果它被改回到先前的值,它不會被算作新的改變。沒有數據的年代表,很難做更多。

select item_id, count(distinct property_2) 
from Table1 
group by item_id 
+0

我確實有一列插入時間。我剛剛編輯了我的問題。 –

0

這是最接近我可以得到您想要的結果。但是,我應該注意到,您正在根據item_id要求更改爲property_2。如果您正在嚴格分析這兩列,則item_id 1和2更改只有1個更改item_id 2.您需要將結果展開爲property_1。希望這fiddle會告訴你爲什麼。

SELECT a.item_id, 
    SUM(
    CASE 
     WHEN a.property_2 <> 
     (SELECT property_2 FROM tbl b 
      WHERE b.item_id = a.item_id AND b.insert_time > a.insert_time LIMIT 1) THEN 1 
     ELSE 0 
    END) AS changes_in_property_2 
FROM tbl a 
GROUP BY a.item_id 
0

我的看法:

SELECT 
    i.item_id, 
    SUM(CASE WHEN i.property_1 != p.property_1 THEN 1 ELSE 0 END) + 1 
     AS changes_1, 
    SUM(CASE WHEN i.property_2 != p.property_2 THEN 1 ELSE 0 END) + 1 
     AS changes_2 
FROM items i 
LEFT JOIN items p 
    ON p.time = 
    (SELECT MAX(q.insert_time) FROM items q 
     WHERE q.insert_time < i.insert_time AND i.item_id = q.item_id) 
GROUP BY i.item_id; 

沒有爲未在i選擇每個項目,有沒有前一個一個條目。儘管這是一個變化,但這也是爲什麼這些和會增加的原因。

+0

@Anime p.time是指什麼?如果「item_id」沒有更改會怎麼樣?看起來你會加1,即使沒有變化。 – Kermit

+0

我知道,這很令人困惑,但如果仔細觀察OP給出的數字,則每個項目的第一個條目本身就被認爲是一個變化。正如你所看到的,即使從「100」到「101」只有一個跳躍,他也希望對「(item_1」,「property_2」)進行2次更改。 對於'i'中的每個條目,'p.time'指同一項目的前一個條目的insert_time。因此,由於我們使用的是內部聯接,因此不會顯示前綴的條目,因此我們必須手動將它們添加到總和中(並且我們知道每個項目總是隻有1)。 –

+0

我剛剛注意到,如果一個項目只有一個條目,最好做一個'LEFT JOIN'。它不會混淆總和,因爲沒有前置任務的條目會將'p.property_1'和'p.property_2'設置爲'NULL',這會導致'CASE ...WHEN'構造返回0。 –

0

我會這樣做,使用用戶定義的變量來跟蹤上一行的值。

SELECT item_id, MAX(c) AS changes_in_property_2 
FROM (
    SELECT IF(@i = item_id, IF(@p = property_2, @c, @c:[email protected]+1), @c:=1) AS c, 
     (@i:=item_id) AS item_id, 
     (@p:=property_2) 
    FROM `no_one_names_their_table_in_sql_questions` AS t, 
    (SELECT @i:=0, @p:=0) AS _init 
    ORDER BY insert_time 
) AS sub 
GROUP BY item_id;