2011-12-15 52 views
44

Trong bảng bên dưới, làm cách nào để nhận được hồ sơ gần đây nhất của id=1 dựa trên cột đăng nhập chứ không phải tất cả 3 bản ghi?MySQL: Nhận hồ sơ gần đây nhất

+----+---------------------+---------+ 
| id | signin    | signout | 
+----+---------------------+---------+ 
| 1 | 2011-12-12 09:27:24 | NULL | 
| 1 | 2011-12-13 09:27:31 | NULL | 
| 1 | 2011-12-14 09:27:34 | NULL | 
| 2 | 2011-12-14 09:28:21 | NULL | 
+----+---------------------+---------+ 

Trả lời

53

Sử dụng tổng hợp MAX(signin) được nhóm theo id. Thao tác này sẽ liệt kê signin gần đây nhất cho mỗi id.

SELECT 
id, 
MAX(signin) AS most_recent_signin 
FROM tbl 
GROUP BY id 

Để nhận được toàn bộ hồ sơ duy nhất, thực hiện một INNER JOIN chống lại một subquery trả về chỉ MAX(signin) mỗi id.

SELECT 
    tbl.id, 
    signin, 
    signout 
FROM tbl 
    INNER JOIN (
    SELECT id, MAX(signin) AS maxsign FROM tbl GROUP BY id 
) ms ON tbl.id = ms.id AND signin = maxsign 
WHERE tbl.id=1 
+0

Đây là những gì làm việc dựa trên ** ** Câu trả lời đầu tiên của bạn: 'CHỌN id, MAX (đăng nhập) TỪ tbl GROUP BY id WHERE id = 1;' – enchance

+0

tôi đã cố gắng để thực hiện các giải pháp thứ 2 (để có được toàn bộ hàng) về tình hình của riêng tôi, nhưng tôi luôn nhận được một tập kết quả rỗng – rantsh

+1

@rantsh Bởi vì nó không chính xác! Tôi đã sửa nó ở trên. Câu trả lời của –

46
SELECT * 
FROM tbl 
WHERE id = 1 
ORDER BY signin DESC 
LIMIT 1; 

Chỉ số hiển nhiên sẽ là trên (id), hoặc một multicolumn index trên (id, signin DESC).

+5

Điều này giống như cách làm sạch nhất! – karancan

+0

Cân nhắc tạo chỉ mục cho cột đăng nhập, nó sẽ tăng tốc quá trình đáng kể –

+0

Sử dụng 'SELECT TOP 1 *' và xóa dòng cuối cùng 'LIMIT 1'. nếu sử dụng SQL Server. Sử dụng ở trên nếu MySQL hoặc Postgres. – jaredbaszler

3
Select [insert your fields here] 
from tablename 
where signin = (select max(signin) from tablename where ID = 1) 
+3

** Không bao giờ sử dụng *, luôn luôn xác định các trường ** – zerkms

+4

@zerkms: Có những tình huống mà '*' thậm chí còn thích *. Đó là một câu hỏi về ràng buộc sớm so với ràng buộc muộn. –

+2

@Erwin Brandstetter: Tôi đã thay đổi ý kiến ​​của mình sau 2 năm thực sự – zerkms

8

xây dựng trên @ xQbert của câu trả lời, bạn có thể tránh được những subquery VÀ làm cho nó chung đủ để lọc theo bất kỳ ID

SELECT id, signin, signout 
FROM dTable 
INNER JOIN(
    SELECT id, MAX(signin) AS signin 
    FROM dTable 
    GROUP BY id 
) AS t1 USING(id, signin) 
+0

Hi truy vấn này hoạt động như thế nào và nó có hiệu quả hơn câu trả lời của xQbert không? Cả hai truy vấn đều chạy cùng lúc với tôi và tôi không hiểu phần sử dụng của truy vấn thay thế thông thường và trên. – ZJS

1
SELECT * FROM (SELECT * FROM tb1 ORDER BY signin DESC) GROUP BY id; 
+1

Điều này không hoạt động. –

0

Tôi đã có một vấn đề tương tự. Tôi cần thiết để có được phiên bản cuối cùng của dịch nội dung trang, nói cách khác - để có được bản ghi cụ thể có số lượng cao nhất trong cột phiên bản. Vì vậy, tôi chọn tất cả các bản ghi được sắp xếp theo phiên bản và sau đó lấy hàng đầu tiên từ kết quả (bằng cách sử dụng mệnh đề LIMIT).

SELECT * 
FROM `page_contents_translations` 
ORDER BY version DESC 
LIMIT 1 
Các vấn đề liên quan