2010-08-31 52 views
1

我有意見這是這個樣子:如何在'之前'刪除某些鍵值已經發生的行?

mysql> select * from p2; 
+---+---------+---------+ 
| k | measure | time_id | 
+---+---------+---------+ 
| D |  200 |  2 | 
| E |  201 |  2 | 
| F |  203 |  2 | 
| A |  20 |  1 | 
| B |  22 |  1 | 
| C |  23 |  1 | 
| D |  100 |  1 | 
| E |  101 |  1 | 
| F |  103 |  1 | 
| G |  4 |  1 | 
| H |  7 |  1 | 
| I |  10 |  1 | 
+---+---------+---------+ 

(k, time_id)是一個獨特的密鑰,上述被大大簡化(會有的time_idk更多的值)。排序順序是time_id DESC(其次是k ASC,但這並不重要)。

我想找到一個SELECT語句,將其過濾到這一點:通過過濾掉行

+---+---------+---------+ 
| k | measure | time_id | 
+---+---------+---------+ 
| D |  200 |  2 | 
| E |  201 |  2 | 
| F |  203 |  2 | 
| A |  20 |  1 | 
| B |  22 |  1 | 
| C |  23 |  1 | 
| G |  4 |  1 | 
| H |  7 |  1 | 
| I |  10 |  1 | 
+---+---------+---------+ 

我想請確保k列值是唯一的,其中k價值已經被使用之前。

在此示例中,在原始視圖中,行0,1,2包含k值D,E和F,但第6,7,8行也是如此,因此第6-8行被刪除以創建第二個視圖。

有沒有一個SELECT語句可以做到這一點?這感覺應該是直截了當的,但我無法弄清楚如何去做。

回答

1

您可能需要使用派生表:

SELECT p2.* 
FROM p2 
JOIN (
      SELECT MAX(time_id) max_time, k 
      FROM  p2 
      GROUP BY k 
     ) d_p2 ON (d_p2.k = p2.k AND d_p2.max_time = p2.time_id); 

或者你也可以使用「空自連接」的方法:

SELECT p2.* 
FROM  p2 
LEFT JOIN p2 AS d_p2 ON d_p2.k = p2.k AND d_p2.time_id > p2.time_id 
WHERE  d_p2.k IS NULL; 

這些應該能正常運行的只要您確定time_id對於每個k都是唯一的。否則,你仍然可能會得到重複的行。

測試用例:

CREATE TABLE p2 (k char(1), measure int, time_id int); 

INSERT INTO p2 VALUES ('D', 200, 2); 
INSERT INTO p2 VALUES ('E', 201, 2); 
INSERT INTO p2 VALUES ('F', 203, 2); 
INSERT INTO p2 VALUES ('A', 20, 1); 
INSERT INTO p2 VALUES ('B', 22, 1); 
INSERT INTO p2 VALUES ('C', 23, 1); 
INSERT INTO p2 VALUES ('D', 100, 1); 
INSERT INTO p2 VALUES ('E', 101, 1); 
INSERT INTO p2 VALUES ('F', 103, 1); 
INSERT INTO p2 VALUES ('G', 4, 1); 
INSERT INTO p2 VALUES ('H', 7, 1); 
INSERT INTO p2 VALUES ('I', 10, 1); 

結果:

+------+---------+---------+ 
| k | measure | time_id | 
+------+---------+---------+ 
| D |  200 |  2 | 
| E |  201 |  2 | 
| F |  203 |  2 | 
| A |  20 |  1 | 
| B |  22 |  1 | 
| C |  23 |  1 | 
| G |  4 |  1 | 
| H |  7 |  1 | 
| I |  10 |  1 | 
+------+---------+---------+ 
9 rows in set (0.00 sec) 
+0

謝謝兩位,邁克爾和丹尼爾。你們都以相同的回答(印象深刻)很快就回來了,但我決定給丹尼爾打勾,因爲我已經決定採用空自聯接方法。 在我的具體情況下,列'k'實際上可以是2列或更多列,其中對於任何給定的time_id值,(k1,k2,...,kn)的組合對於所有行都是唯一的具體的time_id值。 – yassam 2010-09-01 00:16:09

+1

@yassam:如果你的表中有很多行(數以千計),請確保測試兩種方法的性能,因爲在某些情況下可能比另一種方法快得多:http:// kristiannielsen。 livejournal.com/6745.html – 2010-09-01 00:33:00

2
select * from p2 e 
     join (select k, Max(time_id) time_id 
      from p2 
      group by k) t 
     ON (e.k = t.k and e.time_id = t.time_id) 
相關問題