MySQL: Nhận bản ghi gần đây nhất


80

Trong bảng dưới đây, làm thế nào để tôi nhận được chỉ là kỷ lục mới nhất của id=1căn cứ vào cột signin và không phải tất cả 3 hồ sơ?

+----+---------------------+---------+
| 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    |
+----+---------------------+---------+

Câu trả lời:


89

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

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

Để lấy toàn bộ bản ghi đơn, hãy thực hiện INNER JOINmột truy vấn con chỉ trả về 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

Đây là những gì làm việc dựa trên của bạn đầu tiên trả lời:SELECT id, MAX(signin) FROM tbl GROUP BY id WHERE id=1;
Enchance

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

Câu trả lời của @ranth xQbert có phiên bản chính xác của những gì tôi đã có ở trên, nhưng tôi thích giải pháp mà tôi vừa thay đổi hơn.
Michael Berkowski

@MichaelBerkowski, ý bạn là bạn thích giải pháp của tôi hơn? Tôi sẽ không phiền khi nhận được sự ủng hộ cho câu trả lời của mình nếu đúng như vậy
rantsh

1
@ranth Ah, tôi đã không nhận thấy bạn đã thêm một thứ tương tự vào những gì tôi vừa sửa đổi, ngoại trừ thông qua USINGthay vì một cách rõ ràng ON. Bạn đã nhận được +1 :)
Michael Berkowski

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

Chỉ mục rõ ràng sẽ được bật (id), hoặc chỉ mục nhiều cột trên (id, signin DESC).

Thuận tiện cho trường hợp này, MySQL sắp xếp các NULLgiá trị cuối cùng theo thứ tự giảm dần. Đó là những gì bạn thường muốn nếu có thể có NULLcác giá trị: hàng có giá trị không phải là null mới nhất signin.

Để nhận NULLcác giá trị trước tiên:

ORDER BY signin IS NOT NULL, signin DESC

Có liên quan:

Tiêu chuẩn SQL không xác định rõ ràng thứ tự sắp xếp mặc định cho NULLcác giá trị. Hành vi thay đổi khá nhiều trên các RDBMS khác nhau. Xem:

Nhưng có những sự NULLS FIRST/ NULLS LASTđiều khoản quy định trong tiêu chuẩn SQL và được hỗ trợ bởi hầu hết các RDBMS lớn, nhưng không phải bởi MySQL. Xem:


5
Đây là cách làm sạch sẽ nhất!
karancan

Xem xét việc tạo index cho cột đăng nhập, nó sẽ đẩy nhanh quá trình đáng kể
Alexei Tenitski

Sử dụng SELECT TOP 1 *và loại bỏ LIMIT 1dòng cuối cùng. nếu sử dụng SQL Server. Sử dụng ở trên nếu MySQL hoặc Postgres.
jaredbaszler

Sạch sẽ nhất. . . . . . . .
stigzler

Đơn giản và sạch sẽ!
Jeremy Swagger

9

Dựa trên câu trả lời của @ xQbert, bạn có thể tránh truy vấn con VÀ làm cho nó đủ chung để lọc theo bất kỳ ID nào

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

Xin chào, 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 một lúc đối với tôi và tôi không hiểu phần sử dụng của truy vấn thay thế những gì thường và trên.
ZJS

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


1

Tôi đã có một vấn đề tương tự. Nói cách khác, tôi cần lấy phiên bản cuối cùng của bản dịch nội dung trang - để có được bản ghi cụ thể có số 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

1

Cách đơn giản để đạt được

Tôi biết đó là một câu hỏi cũ. Bạn cũng có thể làm điều gì đó như

SELECT * FROM Table WHERE id=1 ORDER BY signin DESC

Ở trên, truy vấn bản ghi đầu tiên sẽ là bản ghi gần đây nhất.

Đối với chỉ một bản ghi, bạn có thể sử dụng một cái gì đó như

SELECT top(1) * FROM Table WHERE id=1 ORDER BY signin DESC

Truy vấn trên sẽ chỉ trả về một bản ghi mới nhất.

Chúc mừng!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.