복붙노트

[SQL] 열에 최대 값 행만에서 SQL [중복]

SQL

열에 최대 값 행만에서 SQL [중복]

내가 문서에 대한이 테이블 (여기 단순화 된 버전)이 :

+------+-------+--------------------------------------+
| id   | rev   | content                              |
+------+-------+--------------------------------------+
| 1    | 1     | ...                                  |
| 2    | 1     | ...                                  |
| 1    | 2     | ...                                  |
| 1    | 3     | ...                                  |
+------+-------+--------------------------------------+

어떻게 하나의 ID 당 행 만 큰 회전을 선택합니까? 상기 데이터를 상기 결과는 두 개의 행을 포함한다 : [1,3, ...]와 [2, 1, ...]. 내가 MySQL을 사용하고 있습니다.

현재 내가 결과 집합에서 이전 회전 속도를 올린다을 감지하고 이상 쓰기 위해 while 루프에서 검사를 사용합니다. 하지만이 결과를 달성하는 유일한 방법이다? 는 SQL 솔루션은 없을까?

최신 정보 답변을 제안하는 SQL 솔루션, 그리고 여기에 sqlfiddle 데모가있다.

업데이트 2 나는 위의 sqlfiddle, 질문은 답변의 upvote에 속도를 능가 upvoted되는 속도를 추가 한 후 나타났습니다. 즉, 의도되지 않았습니다! 바이올린은 답변, 특히 허용 대답을 기반으로합니다.

해결법

  1. ==============================

    1.당신이 필요로하는 모두는 MAX 집계 함수와 GROUP BY 절입니다 :

    당신이 필요로하는 모두는 MAX 집계 함수와 GROUP BY 절입니다 :

    SELECT id, MAX(rev)
    FROM YourTable
    GROUP BY id
    

    난 그냥 당신이 아니라 내용 열을 필요로 나타났습니다.

    이는 SQL에서 매우 일반적인 질문 : 어떤 그룹 식별자 당 열의 일부 최대 값을 가진 행에 대한 모든 데이터를 찾을 수 있습니다. 내가 듣고 내 경력 동안 많은 그. 사실, 그것은 하나의 내가 현재 작업의 기술 인터뷰에서 응답 한 질문이었다.

    큰-N 당 그룹 : StackOverflow의 커뮤니티 그냥 같은 질문을 처리하는 하나의 태그를 만들었다 고 실제로, 이렇게 일반적이다.

    기본적으로, 당신은 그 문제를 해결하는 두 가지 방법이있다 :

    이 방법에서는 먼저 찾을 그룹 식별자, 최대 값 인 그룹 (이미 위의 해결) 하위 쿼리한다. 그럼 당신은 그룹 식별자 및 최대 값 인 그룹 모두 평등 하위 쿼리에 테이블을 조인

    SELECT a.id, a.rev, a.contents
    FROM YourTable a
    INNER JOIN (
        SELECT id, MAX(rev) rev
        FROM YourTable
        GROUP BY id
    ) b ON a.id = b.id AND a.rev = b.rev
    

    이 방법에서는 자체 테이블을 조인 떠났다. 평등 그룹 식별자 간다. 그런 다음,이 개 스마트 이동 :

    당신이와 끝까지 그래서 :

    SELECT a.*
    FROM YourTable a
    LEFT OUTER JOIN YourTable b
        ON a.id = b.id AND a.rev < b.rev
    WHERE b.id IS NULL;
    

    둘 다 똑같은 결과를 가지고 접근한다.

    당신은 최대 값 인 그룹 그룹 식별자를 가진 두 개의 행이있는 경우, 두 행은 두 가지 접근 방식의 결과에있을 것입니다.

    두 가지 접근법 따라서,에 관계없이 "맛"에, 당신의 마음에 드는 RDBMS와 함께 작동합니다, SQL ANSI 호환입니다.

    두 가지 접근법은 (RDBMS, DB 구조, 인덱스 등) 그러나 귀하의 마일리지가 다를 수 있습니다, 또한 성능 친절합니다. 그래서 당신은 다른 벤치 마크를 통해 한 가지 방법을 선택합니다. 그리고 반드시 당신에게 감각의 대부분을 구성하는 하나 선택합니다.

  2. ==============================

    2.내 취향은 가능한 한 작은 코드로 사용하는 것입니다 ...

    내 취향은 가능한 한 작은 코드로 사용하는 것입니다 ...

    당신은 IN 사용하여 작업을 수행 할 수 있습니다 이 시도:

    SELECT * 
    FROM t1 WHERE (id,rev) IN 
    ( SELECT id, MAX(rev)
      FROM t1
      GROUP BY id
    )
    

    내 마음에 덜 읽고 유지하기 위해 쉽게 ... 복잡하다.

  3. ==============================

    3.나는 아무 대답이 SQL 창 기능 솔루션을 제공 없음을 깜짝 놀라게하고있다 :

    나는 아무 대답이 SQL 창 기능 솔루션을 제공 없음을 깜짝 놀라게하고있다 :

    SELECT a.id, a.rev, a.contents
      FROM (SELECT id, rev, contents,
                   ROW_NUMBER() OVER (PARTITION BY id ORDER BY rev DESC) rank
              FROM YourTable) a
     WHERE a.rank = 1 
    

    2003 이상 ANSI / ISO 표준 SQL로 확장 : SQL 표준 ANSI / ISO 표준 SQL에 추가 2008, 윈도우 (또는 윈도) 기능은 이제 모든 주요 공급 업체와 사용할 수 있습니다. RANK, DENSE_RANK, PERSENT_RANK : 넥타이 문제를 처리 할 수 ​​순위 기능의 많은 종류가 있습니다.

  4. ==============================

    4.또 다른 해결책은 상관 하위 쿼리를 사용하는 것입니다 :

    또 다른 해결책은 상관 하위 쿼리를 사용하는 것입니다 :

    select yt.id, yt.rev, yt.contents
        from YourTable yt
        where rev = 
            (select max(rev) from YourTable st where yt.id=st.id)
    

    (ID, REV)에 인덱스를 갖는 거의 같은 간단한 룩업 부질 렌더링 ...

    1-3 : ~ 100 만 기록, 그룹 크기가되는 InnoDB의 테이블 MySQL의 측정을 기반으로 AdrianCarneiro의 대답 (하위 쿼리, leftjoin), @의 솔루션에 대한 비교는 다음과 같습니다.

    동안 전체 테이블 스캔 하위 쿼리 / leftjoin / 상관 타이밍이 직접 조회 또는 배치에 관해서 6/8/9, 서로 관계 (의 ID (1,2,3)), 하위 쿼리가 훨씬 느린 후 다른 사람이다 ( 때문에) 서브 쿼리를 다시 실행합니다. 그러나 나는 leftjoin과 속도에 상관 솔루션 구별을 couldnt.

    leftjoin이 * N 생성으로 마지막으로 참고, (N + 1) / 2의 성능은 크게 그룹의 크기에 의해 영향을받을 수있는 그룹에 조인 ...

  5. ==============================

    5.나는 성능에 대한 신뢰도를 보장 할 수 없습니다, 그러나 여기에서의 Microsoft Excel의 한계에서 영감을 속임수입니다. 그것은 좋은 기능을 가지고 있습니다

    나는 성능에 대한 신뢰도를 보장 할 수 없습니다, 그러나 여기에서의 Microsoft Excel의 한계에서 영감을 속임수입니다. 그것은 좋은 기능을 가지고 있습니다

    좋은 물건

    접근하다

    그것은 조금 못생긴 비트이며 레브 컬럼의 유효한 값의 범위에 대해 뭔가를 알고 있어야합니다. 우리가 레브 열이 0.00와 999을 포함하여 소수 사이의 숫자입니다 만 지금까지 소수점의 오른쪽에 두 자리가 될 것 (예를 들어, 34.17 유효한 값이 될 것이다) 알고 있다고 가정하자.

    물건의 요점은 당신이 원하는 데이터와 함께 차 비교 필드를 포장 / 문자열을 연결하여 하나의 합성 열을 만들 수 있다는 것입니다. 이러한 방법으로, 당신은 (그것이 하나의 컬럼에 포장되어 있기 때문에) 모든 데이터를 반환하는 SQL의 MAX () 집계 함수를 강제 할 수 있습니다. 그런 다음 데이터 압축을 해제해야합니다.

    다음은 SQL로 작성, 위의 예에 보이는 방법

    SELECT id, 
           CAST(SUBSTRING(max(packed_col) FROM 2 FOR 6) AS float) as max_rev,
           SUBSTRING(max(packed_col) FROM 11) AS content_for_max_rev 
    FROM  (SELECT id, 
           CAST(1000 + rev + .001 as CHAR) || '---' || CAST(content AS char) AS packed_col
           FROM yourtable
          ) 
    GROUP BY id
    

    패킹은 예를 들면되도록 REV의 값에 관계없이 공지 된 글자의 숫자로 올린다 열을 강제로 시작

    당신은 바로, 두 숫자의 문자열 비교는 두 숫자의 숫자 비교와 같은 "최대"양보해야 할 그것은 한 형태 또는 다른에서 꽤 많이 사용할 수있는 문자열 기능을 (사용하여 원래 번호로 다시 변환하기 쉬운 경우 어디에나).

  6. ==============================

    6.나는 이것이 가장 쉬운 해결책이라고 생각 :

    나는 이것이 가장 쉬운 해결책이라고 생각 :

    SELECT *
    FROM
        (SELECT *
        FROM Employee
        ORDER BY Salary DESC)
    AS employeesub
    GROUP BY employeesub.Salary;
    

    당신이 필요로 단지 하나의 행이 일어날 경우에도 쉽게 :

    SELECT *
    FROM Employee
    ORDER BY Employee.Salary DESC
    LIMIT 1
    

    나는 또한, 분해 이해하고, 다른 목적으로 수정하는 가장 쉬운 생각 :

    이 방법을 이해, 이러한 유사한 문제 중 하나를 해결하는 것은 사소한된다 : 가장 낮은 급여 (ASC로 변경 DESC)와 직원 수, 종류의 다른 필드의 수단 (변경 주문 BY에 의해, (LIMIT 10로 변경 LIMIT 1) 최고 열 소득 직원 수 Employee.Salary 등 ORDER BY Employee.Commission),에 ..

  7. ==============================

    7.이 같은?

    이 같은?

    SELECT yourtable.id, rev, content
    FROM yourtable
    INNER JOIN (
        SELECT id, max(rev) as maxrev FROM yourtable
        WHERE yourtable
        GROUP BY id
    ) AS child ON (yourtable.id = child.id) AND (yourtable.rev = maxrev)
    
  8. ==============================

    8.일을 할 수있는 또 다른 방법으로는 OVER의 PARTITION 절에 MAX () 분석 함수를 사용

    일을 할 수있는 또 다른 방법으로는 OVER의 PARTITION 절에 MAX () 분석 함수를 사용

    SELECT t.*
      FROM
        (
        SELECT id
              ,rev
              ,contents
              ,MAX(rev) OVER (PARTITION BY id) as max_rev
          FROM YourTable
        ) t
      WHERE t.rev = t.max_rev 
    

    이미이 게시물에 설명 된 다른 ROW_NUMBER () OVER 파티션 솔루션입니다

    SELECT t.*
      FROM
        (
        SELECT id
              ,rev
              ,contents
              ,ROW_NUMBER() OVER (PARTITION BY id ORDER BY rev DESC) rank
          FROM YourTable
        ) t
      WHERE t.rank = 1 
    

    오라클 10g에 잘이 2 SELECT 작업.

    MAX () 용액을 확실히 실행하는 FASTER ROW_NUMBER () 용액 때문에 MAX () 복잡성 O (N) 동안 테이블의 레코드의 수를 나타내는 N ROW_NUMBER ()이 최소 복잡도 O (n.log (N))에있다!

  9. ==============================

    9.나는이 문제에 대한 NOT 존재 기반 솔루션을 사용하려면 :

    나는이 문제에 대한 NOT 존재 기반 솔루션을 사용하려면 :

    SELECT 
      id, 
      rev
      -- you can select other columns here
    FROM YourTable t
    WHERE NOT EXISTS (
       SELECT * FROM YourTable t WHERE t.id = id AND rev > t.rev
    )
    

    이 그룹 내 최대 값을 갖는 모든 레코드를 선택하고 다른 열을 선택할 수 있습니다.

  10. ==============================

    10.이 문제와 관련하여 가장 인기있는 질문이기 때문에, 여기뿐만 아니라 그것을 또 다른 답을 다시 게시합니다 :

    이 문제와 관련하여 가장 인기있는 질문이기 때문에, 여기뿐만 아니라 그것을 또 다른 답을 다시 게시합니다 :

    이 (하지만 MySQL은) 할 수있는 간단한 방법이있을 것 같습니다 :

    select *
    from (select * from mytable order by id, rev desc ) x
    group by id
    

    이 문제에 등의 간결하고 우아한 답을 제공하는이 질문에 사용자 보헤미안의하십시오 신용 대답.

  11. ==============================

    11.내가 좀처럼 언급되지 참조 세 번째 솔루션은 다음과 같이 MySQL의 특정와 외모입니다 :

    내가 좀처럼 언급되지 참조 세 번째 솔루션은 다음과 같이 MySQL의 특정와 외모입니다 :

    SELECT id, MAX(rev) AS rev
     , 0+SUBSTRING_INDEX(GROUP_CONCAT(numeric_content ORDER BY rev DESC), ',', 1) AS numeric_content
    FROM t1
    GROUP BY id
    

    네, 그것은 끔찍한 보이는 (다시 문자열 등으로 변환)하지만 내 경험에 보통 빨리 다른 솔루션에 비해입니다. 어쩌면 그냥 내 사용 사례에 대한,하지만 난 기록의 수백만 많은 고유 ID를 가진 테이블에 그것을 사용하고있다. (나는이 해결책을 왔을 때 5.0 일 적어도) MySQL은 다른 솔루션을 최적화에 아주 나쁜이기 때문에 어쩌면 그것은이다.

    한 가지 중요한 점은 GROUP_CONCAT 그것을 구축 할 수있는 문자열의 최대 길이를 가지고 있다는 것입니다. 당신은 아마 group_concat_max_len 변수를 설정하여이 제한을 마련하고자합니다. 그리고 당신은 많은 수의 행이있는 경우이 확장에 제한이 될 것이라는 점을 명심하십시오.

    콘텐츠 필드가 이미 텍스트 인 경우 어쨌든, 위에서 직접 작동하지 않습니다. 이 경우 당신은 아마 어쩌면 \ 0과 같은 다른 구분 기호를 사용하고 싶습니다. 또한 빨리 group_concat_max_len 한계로 실행하겠습니다.

  12. ==============================

    12.당신은 선택 문에 많은 분야가 있고 최적화 된 코드를 통해 해당 필드의 모든 최신 값을 원하는 경우 :

    당신은 선택 문에 많은 분야가 있고 최적화 된 코드를 통해 해당 필드의 모든 최신 값을 원하는 경우 :

    select * from
    (select * from table_name
    order by id,rev desc) temp
    group by id 
    
  13. ==============================

    13.NOT MySQL은,하지만 다른 사람이 질문을 발견하고 SQL을 사용하는 또 다른 방법은 큰-N 당 그룹 문제가 사용하는 크로스 MS SQL에서 적용을 해결하기 위해

    NOT MySQL은,하지만 다른 사람이 질문을 발견하고 SQL을 사용하는 또 다른 방법은 큰-N 당 그룹 문제가 사용하는 크로스 MS SQL에서 적용을 해결하기 위해

    WITH DocIds AS (SELECT DISTINCT id FROM docs)
    
    SELECT d2.id, d2.rev, d2.content
    FROM DocIds d1
    CROSS APPLY (
      SELECT Top 1 * FROM docs d
      WHERE d.id = d1.id
      ORDER BY rev DESC
    ) d2
    
  14. ==============================

    14.나는 당신이 원하는 생각?

    나는 당신이 원하는 생각?

    select * from docs where (id, rev) IN (select id, max(rev) as rev from docs group by id order by id)  
    

    SQL 바이올린 : 여기 확인

  15. ==============================

    15.

    SELECT *
    FROM Employee
    where Employee.Salary in (select max(salary) from Employee group by Employe_id)
    ORDER BY Employee.Salary
    
  16. ==============================

    16.나는 이것을 사용합니다 :

    나는 이것을 사용합니다 :

    select t.*
    from test as t
    join
       (select max(rev) as rev
        from test
        group by id) as o
    on o.rev = t.rev
    

    하위 쿼리 SELECT도 어쩌면 eficient하지만, JOIN 절을에하는 것은 가능한 것으로 보인다되지 않습니다. 나는 쿼리를 최적화에 전문가는 아니지만 MySQL은, PostgreSQL을, 파이어 버드에서 시도하고이 일이 아주 좋은 않습니다.

    여러 조인 및 WHERE 절을이 스키마를 사용할 수 있습니다. 그것은 내 작업의 예이다 (표 "FIRMY"와 당신의 문제와 동일 해결) :

    select *
    from platnosci as p
    join firmy as f
    on p.id_rel_firmy = f.id_rel
    join (select max(id_obj) as id_obj
          from firmy
          group by id_rel) as o
    on o.id_obj = f.id_obj and p.od > '2014-03-01'
    

    이 테이블 레코드의 수만 수천있는에 요청하고, 정말 너무 강하지 않은 컴퓨터에 미만 0.01 초 걸립니다.

    (이 곳 위에서 언급 한대로) 나는 절에서 사용하지 않을 것입니다. IN은 콘스탄스의 짧은 목록과 함께 사용하기 위해 제공되며,하지 하위 쿼리를 기반으로 쿼리 필터로. IN에서 하위 쿼리가 매우 오랜 시간 동안 완료되지 않고 쿼리를 만들 수있는 모든 스캔 된 레코드를 수행하기 때문이다.

  17. ==============================

    17.이건 어때:

    이건 어때:

    SELECT all_fields.*  
    FROM (SELECT id, MAX(rev) FROM yourtable GROUP BY id) AS max_recs  
    LEFT OUTER JOIN yourtable AS all_fields 
    ON max_recs.id = all_fields.id
    
  18. ==============================

    18.이 솔루션은 따라서이 빠르다, YourTable에서 단 하나의 선택을합니다. 그것은 sqlfiddle.com에 시험에 따라 (SQLite는 제거 DESC를위한)에만 MySQL과 SQLite는 작동합니다. 어쩌면 그것은 내가 익숙하지 않은 나는 다른 언어에 대한 작업을 쥐게 할 수 있습니다.

    이 솔루션은 따라서이 빠르다, YourTable에서 단 하나의 선택을합니다. 그것은 sqlfiddle.com에 시험에 따라 (SQLite는 제거 DESC를위한)에만 MySQL과 SQLite는 작동합니다. 어쩌면 그것은 내가 익숙하지 않은 나는 다른 언어에 대한 작업을 쥐게 할 수 있습니다.

    SELECT *
    FROM ( SELECT *
           FROM ( SELECT 1 as id, 1 as rev, 'content1' as content
                  UNION
                  SELECT 2, 1, 'content2'
                  UNION
                  SELECT 1, 2, 'content3'
                  UNION
                  SELECT 1, 3, 'content4'
                ) as YourTable
           ORDER BY id, rev DESC
       ) as YourTable
    GROUP BY id
    
  19. ==============================

    19.여기에 일을하는 좋은 방법입니다

    여기에 일을하는 좋은 방법입니다

    다음 코드를 사용합니다 :

    with temp as  ( 
    select count(field1) as summ , field1
    from table_name
    group by field1 )
    select * from temp where summ = (select max(summ) from temp)
    
  20. ==============================

    20.나는 약간의 열을 기준으로 레코드를 순위에 의해이 일을 좋아한다. 이 경우, 랭크 REV 값 ID별로 그룹화. 높은 회전을 가진 사람들은 낮은 순위를해야합니다. 그래서 가장 높은 REV 1의 순위해야합니다.

    나는 약간의 열을 기준으로 레코드를 순위에 의해이 일을 좋아한다. 이 경우, 랭크 REV 값 ID별로 그룹화. 높은 회전을 가진 사람들은 낮은 순위를해야합니다. 그래서 가장 높은 REV 1의 순위해야합니다.

    select id, rev, content
    from
     (select
        @rowNum := if(@prevValue = id, @rowNum+1, 1) as row_num,
        id, rev, content,
        @prevValue := id
      from
       (select id, rev, content from YOURTABLE order by id asc, rev desc) TEMP,
       (select @rowNum := 1 from DUAL) X,
       (select @prevValue := -1 from DUAL) Y) TEMP
    where row_num = 1;
    

    확실하지 변수를 도입하면 모든 것이 느리게 만드는 경우. 그러나 적어도 나는 두 번 YOURTABLE를 조회하고 있지 않다.

  21. ==============================

    21.가장 REV 값으로 한 각 그룹의 첫 번째 행을 준해서 특정 ID 역순으로 올린다 필드 정렬.

    가장 REV 값으로 한 각 그룹의 첫 번째 행을 준해서 특정 ID 역순으로 올린다 필드 정렬.

    SELECT * FROM (SELECT * FROM table1 ORDER BY id, rev DESC) X GROUP BY X.id;
    

    다음과 같은 데이터를 http://sqlfiddle.com/에서 테스트

    CREATE TABLE table1
        (`id` int, `rev` int, `content` varchar(11));
    
    INSERT INTO table1
        (`id`, `rev`, `content`)
    VALUES
        (1, 1, 'One-One'),
        (1, 2, 'One-Two'),
        (2, 1, 'Two-One'),
        (2, 2, 'Two-Two'),
        (3, 2, 'Three-Two'),
        (3, 1, 'Three-One'),
        (3, 3, 'Three-Three')
    ;
    

    이것은 MySQL의 5.5 및 5.6에서 다음과 같은 결과를 주었다

    id  rev content
    1   2   One-Two
    2   2   Two-Two
    3   3   Three-Two
    
  22. ==============================

    22.여기 누군가 도움이 될 것입니다 또 다른 솔루션 희망입니다

    여기 누군가 도움이 될 것입니다 또 다른 솔루션 희망입니다

    Select a.id , a.rev, a.content from Table1 a
    inner join 
    (SELECT id, max(rev) rev FROM Table1 GROUP BY id) x on x.id =a.id and x.rev =a.rev
    
  23. ==============================

    23.이 답변 아무도 나를 위해 일한 없다.

    이 답변 아무도 나를 위해 일한 없다.

    이것은 나를 위해 일한 것입니다.

    with score as (select max(score_up) from history)
    select history.* from score, history where history.score_up = score.max
    
  24. ==============================

    24.여기에 해당 필드의 최대 값을 갖는 필드와 레코드를 검색하는 또 다른 솔루션입니다. 이것은의 플랫폼 I 작업입니다 SQL400 작동합니다. 이 예에서, 필드 입력란 5의 최대 값으로 레코드는 다음의 SQL 문에 의해 검색됩니다.

    여기에 해당 필드의 최대 값을 갖는 필드와 레코드를 검색하는 또 다른 솔루션입니다. 이것은의 플랫폼 I 작업입니다 SQL400 작동합니다. 이 예에서, 필드 입력란 5의 최대 값으로 레코드는 다음의 SQL 문에 의해 검색됩니다.

    SELECT A.KEYFIELD1, A.KEYFIELD2, A.FIELD3, A.FIELD4, A.FIELD5
      FROM MYFILE A
     WHERE RRN(A) IN
       (SELECT RRN(B) 
          FROM MYFILE B
         WHERE B.KEYFIELD1 = A.KEYFIELD1 AND B.KEYFIELD2 = A.KEYFIELD2
         ORDER BY B.FIELD5 DESC
         FETCH FIRST ROW ONLY)
    
  25. ==============================

    25.이것은 순수한 SQL 아니다. 이것은 SQLAlchemy의 ORM을 사용합니다.

    이것은 순수한 SQL 아니다. 이것은 SQLAlchemy의 ORM을 사용합니다.

    나는 특히 외부 부분에 가입, 파이썬 / SQLAlchemy의 버전 아드리안 Carneiro의 답변을 중복 있도록 내가 SQLAlchemy의 도움을 찾고 여기에왔다.

    이 쿼리의 질문에 대한 대답 :

    "당신이 기록이 그룹에 나에게 레코드를 반환 할 수있는 가장 높은 버전 번호가 그 (동일한 ID 기준)".

    이 날,이 업데이트 레코드를 복제 버전 번호를 증가, 나는 시간의 흐름에 따른 변화를 보여 수있는 방법으로 이전 버전의 복사본을 가질 수 있습니다.

    MyTableAlias = aliased(MyTable)
    newest_records = appdb.session.query(MyTable).select_from(join(
        MyTable, 
        MyTableAlias, 
        onclause=and_(
            MyTable.id == MyTableAlias.id,
            MyTable.version_int < MyTableAlias.version_int
        ),
        isouter=True
        )
    ).filter(
        MyTableAlias.id  == None,
    ).all()
    

    PostgreSQL의 데이터베이스에서 테스트.

  26. ==============================

    26.난 내 자신의 문제를 해결하기 위해 아래의 사용. 내가 먼저 임시 테이블을 생성하고 고유 한 ID 당 최대 회전 값을 삽입.

    난 내 자신의 문제를 해결하기 위해 아래의 사용. 내가 먼저 임시 테이블을 생성하고 고유 한 ID 당 최대 회전 값을 삽입.

    CREATE TABLE #temp1
    (
        id varchar(20)
        , rev int
    )
    INSERT INTO #temp1
    SELECT a.id, MAX(a.rev) as rev
    FROM 
        (
            SELECT id, content, SUM(rev) as rev
            FROM YourTable
            GROUP BY id, content
        ) as a 
    GROUP BY a.id
    ORDER BY a.id
    

    그때 나는 가능한 ID / 콘텐츠 조합의 모든이 최대 값 (#의 TEMP1)에 가입. 이렇게하면 자연스럽게 비 최대 ID / 컨텐츠 조합을 필터링하고, 각각의 유일한 최대 회전 값을 왼쪽입니다.

    SELECT a.id, a.rev, content
    FROM #temp1 as a
    LEFT JOIN
        (
            SELECT id, content, SUM(rev) as rev
            FROM YourTable
            GROUP BY id, content
        ) as b on a.id = b.id and a.rev = b.rev
    GROUP BY a.id, a.rev, b.content
    ORDER BY a.id
    
  27. ==============================

    27.당신은 MAX 하나 개 maxRevId 값으로 회전 및 ID를 결합 () 한 후 원래 값으로 다시 분할 할 때 가입없이 당신은 선택을 할 수 있습니다 :

    당신은 MAX 하나 개 maxRevId 값으로 회전 및 ID를 결합 () 한 후 원래 값으로 다시 분할 할 때 가입없이 당신은 선택을 할 수 있습니다 :

    SELECT maxRevId & ((1 << 32) - 1) as id, maxRevId >> 32 AS rev
    FROM (SELECT MAX(((rev << 32) | id)) AS maxRevId
          FROM YourTable
          GROUP BY id) x;
    

    복잡한 대신 단일 테이블의 조인이 특히 빠른 때이다. 복잡한 두 번 할 것 가입 전통적인 방법으로.

    REV 및 ID가 UNSIGNED INT (32 비트) 및 BIGINT UNSIGNED 결합 맞는 값 (64 비트) 인 경우, 상기 조합은 비트 기능 간단하다. 아이디 및 회전이 32 비트 값보다 크거나 여러 열을 만든 경우, 당신은 예를 들어,에 값을 결합 할 필요가 MAX 적합한 패딩 이진 값 ().

  28. from https://stackoverflow.com/questions/7745609/sql-select-only-rows-with-max-value-on-a-column by cc-by-sa and MIT license