2009-08-20 35 views
5

Hãy nhìn vào bảng MySQL dưới đây gọi là "bài viết":Tìm hàng với giá trị lớn nhất của id trong MySQL

+----+-----------+---------+------------------------+--------------------------+ 
| id | articleId | version | title     | content     | 
+----+-----------+---------+------------------------+--------------------------+ 
| 1 |   1 | 0.0  | ArticleNo.1 title v0.0 | ArticleNo.1 content v0.0 | 
| 2 |   1 | 1.0  | ArticleNo.1 title v1.0 | ArticleNo.1 content v1.0 | 
| 3 |   1 | 1.5  | ArticleNo.1 title v1.5 | ArticleNo.1 content v1.5 | 
| 4 |   1 | 2.0  | ArticleNo.1 title v2.0 | ArticleNo.1 content v2.0 | 
| 5 |   2 | 1.0  | ArticleNo.2 title v1.0 | ArticleNo.2 content v1.0 | 
| 6 |   2 | 2.0  | ArticleNo.2 title v2.0 | ArticleNo.2 content v2.0 | 
+----+-----------+---------+------------------------+--------------------------+ 

Im cố gắng để đưa ra một truy vấn để trở Articles.id nơi Articles.version là số lượng tối đa.

Bảng Các bài viết thực tế chứa hơn 10.000 mục nhập.

Vì vậy, trong ví dụ này, tôi CHỈ muốn Articles.id 4 và 6 được trả lại. Tôi đã nhìn vào từ khóa khác biệt và chức năng max() nhưng không thể dường như đinh nó.

Bất kỳ lời đề nghị đánh giá cao ...

Trả lời

4

Bạn cần một truy vấn phụ ở đây:

SELECT a.id, a.version 
FROM articles a 
WHERE a.version = (
    SELECT MAX(version) 
    FROM articles b 
    WHERE b.articleId = a.articleId 
) 
+0

Điều này trả về tất cả các phiên bản mới nhất của bài viết, loại bỏ các phiên bản cũ/cũ hơn. Nice truy vấn chàng trai cảm ơn rất nhiều! –

+0

Chỉ để lưu nội dung: T.J. Crowder chỉ ra trong câu trả lời của anh ta, rằng một truy vấn phụ không phải là bắt buộc: nó có thể được thực hiện với một JOIN LEFT, quá. – soulmerge

4

Bạn có thể sử dụng một subquery đây:

select 
    a.id 
from 
    articles a 
where 
    a.version = (select max(version) from articles) 

Vì đây không phải là một subquery tương quan, nó sẽ là khá nhanh (nhanh hoặc nhanh hơn một tham gia), vì vậy bạn không cần phải lo lắng về điều đó. Nhưng nó sẽ trả về tất cả các giá trị có tối đa articleid.

Tất nhiên, tôi khuyên bạn nên ném chỉ mục trên articleid (giả sử id đã được nhóm). Điều đó sẽ giúp nó trở lại nhanh hơn.

Như đã đề cập trong các ý kiến, nếu bạn muốn để có được phiên bản tối đa cho mỗi articleid, bạn có thể làm như sau:

select 
    a.id 
from 
    articles a 
    inner join (select articleid, max(version) 
       from articles group by articleid) as b on 
     a.articleid = b.articleid 
     and a.version = b.version 

này sẽ tạo ra một tham gia ra khỏi subquery đó và thường được nhanh hơn nhiều so một truy vấn con tương quan chọn mức tối đa cho mỗi articleid.

+1

Điều này không đúng - việc này chọn ID bài viết tối đa là tối đa, chứ không phải phiên bản bài viết. – tw39124

+0

@Tom: Vâng, và bây giờ tôi đã sửa nó, nên nó đúng. – Eric

+0

Lưu ý rằng điều này sẽ chỉ chọn các bài viết có phiên bản * cùng *. Nếu bạn muốn tìm nạp phiên bản mới nhất của * mỗi bài viết *, hãy xem câu trả lời của tôi bên dưới. – soulmerge

1

SELECT Articles.id FROM Articles WHERE Articles.version IN (SELECT MAX(Articles.version) FROM Articles)

1

có lẽ cái gì đó như:

select * from bài viết nơi ArticleID trong (chọn max (articleversion) từ bài viết)

1

Bạn có thể làm

SELECT articles.id 
    FROM articles a 
WHERE NOT EXISTS(SELECT * FROM articles a2 WHERE a2.version > a.version) 

I don' t biết MySQL sẽ thực hiện với nó, nhưng Oracle và SQL server là tốt với nó.

5

Từ MySQL manual, điều này làm các trick:

SELECT a1.id 
FROM Articles a1 
LEFT JOIN Articles a2 ON a1.articleId = a2.articleId AND a1.version < a2.version 
WHERE a2.articleId IS NULL; 

Xem liên kết cho lý do.

+0

Cũng lưu ý rằng truy vấn phụ trong mệnh đề WHERE trong MySQL có thể được thực thi cho mỗi hàng trong kết quả, vì vậy đây có lẽ là câu trả lời có hiệu suất tốt nhất. –

1

Tất cả câu trả lời ở trên có thể giải quyết được sự cố đã nêu của DJDonaL3000. Tuy nhiên, hầu hết trong số đó là các truy vấn phụ tương quan cản trở hiệu suất của ứng dụng. Nếu bạn đang sử dụng một ứng dụng đám mây thì tôi khuyên bạn không nên sử dụng các truy vấn trên. Cách tốt nhất là duy trì hai bảng, A và B. A luôn chứa phiên bản mới nhất của bài báo và B có chi tiết về tất cả các phiên bản. Vấn đề là sẽ có nhiều cập nhật và chèn thêm vào các bảng, nhưng tìm nạp sẽ nhanh hơn khi bạn chỉ cần thực hiện truy vấn chọn bình thường trong bảng A.Làm theo nhóm và tối đa trong truy vấn bên trong sẽ tính phí cho bạn

Các vấn đề liên quan