2012-05-29 48 views
1

我已經創建了一個僅用於插入表格以達到速度和保持歷史記錄的目的。它的結構是非常通用的,如下:SQL只插入表格,如何只選擇最新的條目

`id` bigint(20) unsigned NOT NULL auto_increment, 
    `user_id` bigint(20) unsigned NOT NULL, 
    `property` varchar(32) NOT NULL, 
    `value` longblob NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; 

它只是一個鍵/值表與分配給它的USER_ID。這種方法有其優點,因爲並非所有用戶都具有相同的屬性,所以字段不會浪費在表中。此外,它還允許滾動記錄更改,因爲我可以看到用戶所做的特定屬性的每個更改。

現在,由於此表中沒有發生任何刪除或更新,我可以假設最大的id始終是最新的條目。然而,我想一次選擇多個屬性,例如'address1','address2','city','state',我希望每個屬性都是其最高id的類型的入口。因此,如果他們已經8次更改了他們的'州'屬性,'城市'屬性更改了4次,那麼我只想要一個SELECT返回每個(1個州和1個城市)的最新值。

我不確定這個表格甚至可以用這種類型的表格高效地完成,所以我打開了不同的表格方法。

請讓我知道如果我需要生產更多的信息或更好地澄清我的問題。

=== 我嘗試了以下操作,但最後一次'address2'更改後可能會有3行'address1'更改。也許使用GROUP BY會起作用嗎?

SELECT property, value FROM kvtable WHERE user_id = 1 AND (property = 'address1' OR property = 'address2') ORDER BY id

+1

「*現在,由於此表中沒有刪除或更新,我可以假定最大的id始終是最新的條目*」 - 不,你不能。如果一個'INSERT'指定一個明確的'id' ***'x' ***,那麼稍後一個指定明確的'''''***''''''''''***'x' ***? – eggyal

+0

這是自動增量,不應該明確定義。這仍然是一個安全的假設?我可以添加一個日期列。 – crush

+1

僅僅因爲定義了一個列'AUTO_INCREMENT'並不能阻止用戶在'INSERT'期間提供明確的值 - 如果沒有提供明確的值,它僅僅設置一個遞增的值。一般來說,時間戳列更安全;然而,如果你完全控制了每個'INSERT'操作,並且可以確保沒有提供明確的'id',我*認爲*安全工作的前提是'id'在插入時會嚴格增加。 – eggyal

回答

4

假設你的ID是增量整數和你沒有手動指定出來的順序,你可以在一個子查詢的幾個MAX()聚集做到這一點。子查詢的重點是爲每個用戶返回每個屬性名稱的最新條目。這與整個表格連接以提取相關的屬性值。本質上,子查詢會丟棄每個組中沒有最大(id)的所有行。

SELECT kvtable.* 
FROM 
    kvtable 
    JOIN (
    SELECT 
     MAX(id) AS id, 
     user_id, 
     property 
    FROM kvtable 
    /* optionally limit by user_id */ 
    WHERE user_id = <someuser> 
    GROUP BY user_id, property 
) maxids ON kvtable.id = maxids.id 
+0

這似乎是做這項工作。現在,如果我想限制它到指定ID的用戶,我會追加做JOIN ON語句爲'ON properties_table.id = maxids.id AND properties_table.user_id = 1'例如? – crush

+1

@crush是的,在ON子句中,或者你可以在子查詢中添加一個WHERE子句。 –

+0

太棒了。無論如何,這似乎足夠有效。謝謝您的幫助! – crush