PostgreSQL에서 카테고리별로 최대 날짜 그룹으로 ID를 선택하는 방법은 무엇입니까?


88

예를 들어 카테고리별로 최대 날짜 그룹이있는 id를 선택하고 싶습니다. 결과는 다음과 같습니다. 7, 2, 6

id  category  date
1   a         2013-01-01
2   b         2013-01-03
3   c         2013-01-02
4   a         2013-01-02
5   b         2013-01-02
6   c         2013-01-03
7   a         2013-01-03
8   b         2013-01-01
9   c         2013-01-01

PostgreSQL에서이 작업을 수행하는 방법을 알 수 있습니까?


4
PostgreSQL 버전을 포함하는 것이 항상 현명합니다.
Erwin Brandstetter 2013-06-04

답변:


141

이것은 DISTINCT ON(Postgres 특정 표준 확장)에 대한 완벽한 사용 사례입니다 DISTINCT.

SELECT DISTINCT ON (category)
       id  -- , category, date -- add any other column (expression) from the same row
FROM   tbl
ORDER  BY category, "date" DESC;

내림차순 정렬에주의하십시오. 열이 NULL 일 수있는 경우 다음을 추가 할 수 있습니다 NULLS LAST.

DISTINCT ON가장 간단하고 빠릅니다. 이 관련 답변에 대한 자세한 설명 :

큰 테이블의 경우 다음 대체 방법을 고려하십시오.

많은 행에 대한 성능 최적화 category:


훌륭해 보이지만 이것이 매번 작동한다는 것이 확실합니까?
Atherion 2015 년

@Tixel : 물론입니다. 자세한 내용은 링크를 따르십시오.
Erwin Brandstetter 2015-08-07

21

이걸로 해봐:

SELECT t1.* FROM Table1 t1
JOIN 
(
   SELECT category, MAX(date) AS MAXDATE
   FROM Table1
   GROUP BY category
) t2
ON T1.category = t2.category
AND t1.date = t2.MAXDATE

이 SQLFiddle 보기


1
rank () 창 함수를 사용하는 또 다른 옵션이 있습니다.
데니스 드 Bernardy에

@ user1735921 : Table1에서 모든 열을 가져옵니다. 원하는 것을 선택할 수 있습니다.
Himanshu Jansari

15

또 다른 방법은 first_value창 기능 을 사용하는 것입니다 : http://sqlfiddle.com/#!12/7a145/14

SELECT DISTINCT
  first_value("id") OVER (PARTITION BY "category" ORDER BY "date" DESC) 
FROM Table1
ORDER BY 1;

... 나는 hims056의 제안이 적절한 인덱스가있는 곳에서 일반적으로 더 잘 수행 될 것이라고 생각하지만.

세 번째 해결책은 다음과 같습니다.

SELECT
  id
FROM (
  SELECT
    id,
    row_number() OVER (PARTITION BY "category" ORDER BY "date" DESC) AS rownum
  FROM Table1
) x
WHERE rownum = 1;

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