2013-03-23 34 views
1

我有一張表,它包含多個具有不同ID的行。 (種類很多,ID是唯一的,兩列都被索引) 現在我需要選擇每種類型的ID最高的兩個。 這是我做的。MySQL:選擇所有最高ID的兩種類型

select max(c.id), max(d.id) from theTable c left join 
theTable d on c.id > d.id and c.kind=d.kind 
where c.id > constant group by c.kind; 

但是,上面的查詢表現不佳,並不是一個大的驚喜。 伊夫想通了它的一個更快的版本...

select c.id, max(d.id) from (select max(id) id, kind from theTable  
where id > constatnt group by kind) c left join 
theTable d on c.id > d.id and c.kind=d.kind group by c.kind; 

....但仍是不夠快

有沒有更有效的方式來達到同樣的效果? 謝謝!

編輯: theTbale是一個歷史表,所以我的任務是讓當前值和以前的每個種類和比較它們作爲表達的一部分(邏輯運算,聚結,如果和等)和判斷表達式的結果是不同的

這裏有一個例子結果集:

 
+-----------+-----------+ 
| max(c.id) | max(d.id) | 
+-----------+-----------+ 
|  1747 |  NULL | 
|  1701 |  1432 | 
|  1703 |  1434 | 
|  1706 |  1437 | 
|  1707 |  1438 | 
|  1751 |  NULL | 
|  1713 |  1444 | 
|  1750 |  NULL | 
|  1709 |  1440 | 
|  1742 |  1741 | 
|  1711 |  1442 | 
|  1746 |  1745 | 
|  1708 |  1439 | 
|  1719 |  1450 | 
|  1725 |  1456 | 
|  1723 |  1454 | 
|  1740 |  1733 | 
|  1705 |  1436 | 
|  1702 |  1433 | 
|  1749 |  1748 | 
|  1712 |  1443 | 
|  1718 |  1449 | 
|  1722 |  1453 | 
|  1728 |  1459 | 
|  1721 |  1452 | 
|  1739 |  1731 | 
|  1714 |  1445 | 
|  1717 |  1448 | 
|  1716 |  1447 | 
|  1724 |  1455 | 
|  1710 |  1441 | 
|  1727 |  1458 | 
|  1720 |  1451 | 
|  1738 |  NULL | 
|  1715 |  1446 | 
|  1704 |  1435 | 
|  1726 |  1457 | 
|  1758 |  1757 | 
+-----------+-----------+ 
+0

我沒有看到外連接的原因。 – 2013-03-23 22:26:11

+0

會更快嗎? – 2013-03-23 22:27:41

+0

您能否發佈樣本數據和預期結果?你的任務不是很清楚。性能(特別是對於大型數據集)通常取決於表索引。你有什麼指數? – 2013-03-23 22:31:30

回答

1

下可以執行得很好:

select kind, max(id) as maxid, 
     (select id from t t2 where t2.kind = t.kind and t2.id < max(t1.id) order by id desc limit 1) as secondId 
from t 
group by kind 

這將很好地工作如果kind, id有一個索引。

+0

不要忘記在'id> constant'上過濾。內部查詢可以被重新表述爲'select max(id)t t2,其中t2.kind = t1.kind和t2.id kputnam 2013-03-23 23:02:57

+0

戈登謝謝你的回答。我已經測試過它,它改善了我的第一個查詢,但它比我的第二個查詢慢了40%。然而,我會投你的答案,因爲這是一個很好的解決方案。 – 2013-03-23 23:12:09

+0

@dudelgrincen。 。 。你有'(kind,id)'索引嗎?不是每一個單獨的索引,而是兩個索引(按該順序)。 – 2013-03-23 23:14:49

2

如果不是生產(實物,ID,ID)元組一行對每個善良,你的[R esult設置爲(kind,id)每行兩行?不過,我不確定如果沒有自己運行,這是否會更高效。

 
SELECT x.kind, x.id 
FROM (SELECT a.kind, a.id 
     FROM theTable a 
     LEFT OUTER JOIN theTable b 
      ON a.kind = b.kind 
     AND a.id < b.id 
     GROUP BY a.id 
     HAVING COUNT(*) < 2 
     ORDER BY b.id) x 
WHERE x.id > constant 
ORDER BY x.kind; 

最後ORDER BY條款只是爲了讓您更容易驗證的結果,所以評估性能時忽略它。請注意,某些可能只有一個ID超出了您的常數,因此您將只有一個(kind,id)這一行。

+0

儘管它不是我想要的,但我試過了。我可以使用它,但速度與我的第一次嘗試一樣快。不管怎麼說,還是要謝謝你! :)由於你的時間,我會投你的答案 – 2013-03-23 22:53:52

+0

是的,我確實有足夠的餘地。 – 2013-03-23 23:15:05