MySQL : 최신 기록 가져 오기


80

아래 표에서 3 개 레코드가 아닌 로그인 열 을 기준으로 가장 최근 레코드 만 가져 오려면 어떻게해야 id=1합니까?

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

답변:


90

MAX(signin)ID별로 그룹화 된 집계를 사용하십시오 . signin각에 대한 최신 목록이 표시됩니다 id.

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

전체 단일 레코드를 얻으려면 per id INNER JOIN만 반환하는 하위 쿼리에 대해를 수행하십시오 MAX(signin).

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

다음은 첫 번째 답변을 기반으로 작동 한 것입니다.SELECT id, MAX(signin) FROM tbl GROUP BY id WHERE id=1;
enchance

내 상황에서 두 번째 솔루션 (전체 행을 얻기 위해)을 구현하려고했지만 항상 빈 결과 집합을 얻습니다
rantsh

@rantsh xQbert의 대답에는 내가 원래 가지고 있던 올바른 버전이 있었지만 방금 변경 한 솔루션을 선호합니다.
Michael Berkowski 2013 년

@MichaelBerkowski 당신은 내 솔루션을 선호한다는 뜻입니까? 그럴 경우 내 답변에 대해
찬성 투표를받는 것도 괜찮습니다.

1
@rantsh 아, 방금 수정 한 것과 비슷한 것을 추가했지만 USING명시 적 ON. 당신은 1 : 도착
마이클 Berkowski

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

명백한 색인은 on (id)또는 여러 열 색인이 됩니다.(id, signin DESC) .

이 경우에 편리하게 MySQL은 NULL값 을 내림차순으로 마지막 으로 정렬 합니다 . NULL값 이있을 수있는 경우 일반적으로 원하는 것 입니다. 최신 not-null이있는 행입니다 signin.

NULL먼저 값 을 얻으려면 :

ORDER BY signin IS NOT NULL, signin DESC

관련 :

SQL 표준은 NULL값에 대한 기본 정렬 순서를 명시 적으로 정의하지 않습니다 . 동작은 RDBMS에 따라 상당히 다릅니다. 보다:

그러나이 있다NULLS FIRST /의 NULLS LASTMySQL이 대부분의 주요 RDBMS하여 SQL 표준에 정의 및 지원 조항,하지만은. 보다:


5
이것은 그것을하는 가장 깨끗한 방법처럼 느껴집니다!
karancan

로그인 열에 대한 인덱스 생성을 고려하면 프로세스 속도가 크게 향상됩니다
Alexei Tenitski 2014 년

마지막 줄을 사용 SELECT TOP 1 *하고 제거하십시오 LIMIT 1. SQL Server를 사용하는 경우. MySQL 또는 Postgres 인 경우 위를 사용하십시오.
jaredbaszler

깨끗한. . . . . . . .
stigzler 19.01.05

간단하고 깨끗합니다!
제레미 자신감

9

@xQbert의 답변을 바탕으로 하위 쿼리를 피하고 모든 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)

안녕하세요이 쿼리는 어떻게 작동하며 xQbert의 답변보다 효율적입니까? 두 쿼리 모두 나에게 거의 동시에 실행되며 일반적으로 사용되는 것을 대체하는 쿼리의 사용 부분을 이해하지 못합니다.
ZJS 2013

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


1

비슷한 문제가있었습니다. 즉, 버전 열에서 가장 높은 번호를 가진 특정 레코드를 얻으려면 페이지 콘텐츠 번역의 마지막 버전을 가져와야했습니다. 따라서 버전별로 정렬 된 모든 레코드를 선택한 다음 결과에서 첫 번째 행을 가져옵니다 (LIMIT 절 사용).

SELECT *
FROM `page_contents_translations`
ORDER BY version DESC
LIMIT 1

1

달성하는 간단한 방법

나는 그것이 오래된 질문이라는 것을 안다. 당신은 또한 다음과 같은 것을 할 수 있습니다.

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

위에서 첫 번째 레코드를 쿼리하면 가장 최근 레코드가됩니다.

하나의 레코드에만 다음과 같은 것을 사용할 수 있습니다.

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

위의 쿼리는 하나의 최신 레코드 만 반환합니다.

건배!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.