복붙노트

[SQL] 그룹화 SQL 결과 각 그룹에 대해 최대 값을 기록 받기

SQL

그룹화 SQL 결과 각 그룹에 대해 최대 값을 기록 받기

당신은 어떻게 각 그룹화 세트에 대한 최대 값을 포함하는 행을받을 수 있나요?

나는 좋은 대답 일부 지나치게 복잡한이 질문에 대한 변화, 그리고 아무도를 보았다. 내가 가장 간단한 예를 함께 넣어 시도했다 :

사람, 그룹, 나이 열이 아래 같은 테이블을 감안할 때, 당신은 어떻게 각 그룹에서 가장 오래된 사람을 얻을 것? (그룹 내의 넥타이 첫 알파벳 결과를 제공한다)

Person | Group | Age
---
Bob  | 1     | 32  
Jill | 1     | 34  
Shawn| 1     | 42  
Jake | 2     | 29  
Paul | 2     | 36  
Laura| 2     | 39  

원하는 결과 집합 :

Shawn | 1     | 42    
Laura | 2     | 39  

해결법

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

    1.MySQL의에서이 작업을 수행 할 수있는 슈퍼 간단한 방법이있다 :

    MySQL의에서이 작업을 수행 할 수있는 슈퍼 간단한 방법이있다 :

    select * 
    from (select * from mytable order by `Group`, age desc, Person) x
    group by `Group`
    

    이 작품 MySQL은 당신이 허용하고 있기 때문에하지 집계되지 않은 그룹에 의한 경우 MySQL은 단지 첫 번째 행을 반환하는 열. 이 솔루션은 데이터가 각 그룹에 대해 원하는 행이 처음이라고, 열로 다음 그룹은이 값을 원하는 같은 첫 번째 순서이다.

    (다른 답변을하는 것처럼) 동일한 최대 값이 하나 이상있을 때 당신은 복잡 등) (최대를 찾아보십시오 하위 쿼리, 또한 여러 행을 반환하는 문제를 방지

    참고 :이 MySQL의 전용 솔루션입니다. 라는 메시지와 함께 SQL 구문 오류가 발생합니다 알고있는 다른 모든 데이터베이스는 또는 유사한 "비 집계 열이 GROUP BY 절에 나열되지 않습니다." 이 솔루션은 문서화되지 않은 동작을 사용하기 때문에 그것은 MySQL의 향후 버전이 동작을 변경해야 작업 유지, 더 많은주의가 주장 테스트를 포함 할 수 있습니다.

    버전 5.7 이후, SQL 모드 설정은 그래서 당신이 (이 설정을 제거하는 편집 서버의 옵션 파일)이 옵션이 안됩니다이 작품을 만들기 위해, ONLY_FULL_GROUP_BY 기본적으로 포함되어 있습니다.

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

    2.올바른 솔루션입니다 :

    올바른 솔루션입니다 :

    SELECT o.*
    FROM `Persons` o                    # 'o' from 'oldest person in group'
      LEFT JOIN `Persons` b             # 'b' from 'bigger age'
          ON o.Group = b.Group AND o.Age < b.Age
    WHERE b.Age is NULL                 # bigger age not found
    

    그것은 열 그룹에서 같은 값 열 연령보다 큰 값을 갖는 B의 행을 가진 모든 O에서 각 행에 일치한다. 열 연령의 그룹의 최대 값을 갖지 않는 O에서 모든 행 B의 하나 이상의 행에 일치한다.

    왼쪽은 B에서 널 (NULL)의 전체 행 ( '그룹에 더 큰 시대')와 (자신의 그룹에 혼자있는 사람을 포함) 그룹에서 가장 오래된 사람에 맞는 차종 가입하세요. 사용 INNER 다음 행이 일치하지 않는 차종을 가입하고는 무시됩니다.

    WHERE 절은 B로부터 추출 분야에서 널 (null)을 갖는 행만을 유지한다. 그들은 각 그룹에서 가장 오래된 사람입니다.

    데이터베이스 프로그래밍의 함정을 피하기 :이 솔루션 및 많은 다른 사람이 책 SQL 안티 패턴에 설명되어 있습니다

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

    3.당신은 MAX (그룹)과 나이를 끌어 하위 쿼리에 가입 할 수 있습니다. 이 방법은 대부분의 RDBMS에 걸쳐 휴대용입니다.

    당신은 MAX (그룹)과 나이를 끌어 하위 쿼리에 가입 할 수 있습니다. 이 방법은 대부분의 RDBMS에 걸쳐 휴대용입니다.

    SELECT t1.*
    FROM yourTable t1
    INNER JOIN
    (
        SELECT `Group`, MAX(Age) AS max_age
        FROM yourTable
        GROUP BY `Group`
    ) t2
        ON t1.`Group` = t2.`Group` AND t1.Age = t2.max_age;
    
  4. ==============================

    4.(아마와 MySQL) SQLite는 대한 나의 간단한 해결책 :

    (아마와 MySQL) SQLite는 대한 나의 간단한 해결책 :

    SELECT *, MAX(age) FROM mytable GROUP BY `Group`;
    

    그러나 PostgreSQL의에서 작동하지 않습니다 그리고 아마도 다른 플랫폼.

    PostgreSQL의에서는 DISTINCT ON 절을 사용할 수 있습니다 :

    SELECT DISTINCT ON ("group") * FROM "mytable" ORDER BY "group", "age" DESC;
    
  5. ==============================

    5.위 방법을 사용하여.

    위 방법을 사용하여.

    SELECT @rn :=  CASE WHEN @prev_grp <> groupa THEN 1 ELSE @rn+1 END AS rn,  
       @prev_grp :=groupa,
       person,age,groupa  
    FROM   users,(SELECT @rn := 0) r        
    HAVING rn=1
    ORDER  BY groupa,age DESC,person
    
  6. ==============================

    6.확실하지 MySQL은 ROW_NUMBER 기능이있는 경우. 당신이 그것을 사용할 수 있도록하면 원하는 결과를 얻을 수 있습니다. SQL 서버에서 당신은 비슷한 일을 할 수있는 :

    확실하지 MySQL은 ROW_NUMBER 기능이있는 경우. 당신이 그것을 사용할 수 있도록하면 원하는 결과를 얻을 수 있습니다. SQL 서버에서 당신은 비슷한 일을 할 수있는 :

    CREATE TABLE p
    (
     person NVARCHAR(10),
     gp INT,
     age INT
    );
    GO
    INSERT  INTO p
    VALUES  ('Bob', 1, 32);
    INSERT  INTO p
    VALUES  ('Jill', 1, 34);
    INSERT  INTO p
    VALUES  ('Shawn', 1, 42);
    INSERT  INTO p
    VALUES  ('Jake', 2, 29);
    INSERT  INTO p
    VALUES  ('Paul', 2, 36);
    INSERT  INTO p
    VALUES  ('Laura', 2, 39);
    GO
    
    SELECT  t.person, t.gp, t.age
    FROM    (
             SELECT *,
                    ROW_NUMBER() OVER (PARTITION BY gp ORDER BY age DESC) row
             FROM   p
            ) t
    WHERE   t.row = 1;
    
  7. ==============================

    7.axiac의 솔루션은 결국 나에게 가장 일 것입니다. 계산 된 "최대 값", 두 개의 열에서 파생 : 나는 그러나 추가적인 복잡성을했다.

    axiac의 솔루션은 결국 나에게 가장 일 것입니다. 계산 된 "최대 값", 두 개의 열에서 파생 : 나는 그러나 추가적인 복잡성을했다.

    하자 같은 예제를 사용 : 나는 각 그룹에서 가장 오래된 사람을 부탁합니다. 똑같이 오래된 사람이있는 경우, 가장 높은 사람을.

    나는이 동작을 얻기 위해 왼쪽 두 번 가입 수행했다 :

    SELECT o1.* WHERE
        (SELECT o.*
        FROM `Persons` o
        LEFT JOIN `Persons` b
        ON o.Group = b.Group AND o.Age < b.Age
        WHERE b.Age is NULL) o1
    LEFT JOIN
        (SELECT o.*
        FROM `Persons` o
        LEFT JOIN `Persons` b
        ON o.Group = b.Group AND o.Age < b.Age
        WHERE b.Age is NULL) o2
    ON o1.Group = o2.Group AND o1.Height < o2.Height 
    WHERE o2.Height is NULL;
    

    도움이 되었기를 바랍니다! 나는이 생각을 할 수있는 더 좋은 방법이 있어야한다 생각 ...

  8. ==============================

    8.내 솔루션은 그러나 내 요구 성능의 측면에서 볼 수있는 가장 좋은 방법은 (! 그것은 단지 하나의 쿼리를 사용)이고, 하나의 열을 검색 할 필요가있는 경우에만 작동합니다 :

    내 솔루션은 그러나 내 요구 성능의 측면에서 볼 수있는 가장 좋은 방법은 (! 그것은 단지 하나의 쿼리를 사용)이고, 하나의 열을 검색 할 필요가있는 경우에만 작동합니다 :

    SELECT SUBSTRING_INDEX(GROUP_CONCAT(column_x ORDER BY column_y),',',1) AS xyz,
       column_z
    FROM table_name
    GROUP BY column_z;
    

    그것은 순서 CONCAT 목록을 만들기 위해 GROUP_CONCAT를 사용하고 난 단지 첫 번째로 하위 문자열.

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

    9.CTE를 사용 - 공통 테이블 식을 :

    CTE를 사용 - 공통 테이블 식을 :

    WITH MyCTE(MaxPKID, SomeColumn1)
    AS(
    SELECT MAX(a.MyTablePKID) AS MaxPKID, a.SomeColumn1
    FROM MyTable1 a
    GROUP BY a.SomeColumn1
      )
    SELECT b.MyTablePKID, b.SomeColumn1, b.SomeColumn2 MAX(b.NumEstado)
    FROM MyTable1 b
    INNER JOIN MyCTE c ON c.MaxPKID = b.MyTablePKID
    GROUP BY b.MyTablePKID, b.SomeColumn1, b.SomeColumn2
    
    --Note: MyTablePKID is the PrimaryKey of MyTable
    
  10. ==============================

    10.나는 WHERE IN을 사용하여 간단한 해결책을 가지고 있습니다

    나는 WHERE IN을 사용하여 간단한 해결책을 가지고 있습니다

    SELECT a.* FROM `mytable` AS a    
    WHERE a.age IN( SELECT MAX(b.age) AS age FROM `mytable` AS b GROUP BY b.group )    
    ORDER BY a.group ASC, a.person ASC
    
  11. ==============================

    11.오라클에서 쿼리는 원하는 결과를 줄 수 아래.

    오라클에서 쿼리는 원하는 결과를 줄 수 아래.

    SELECT group,person,Age,
      ROWNUMBER() OVER (PARTITION BY group ORDER BY age desc ,person asc) as rankForEachGroup
      FROM tablename where rankForEachGroup=1
    
  12. ==============================

    12.

    with CTE as 
    (select Person, 
    [Group], Age, RN= Row_Number() 
    over(partition by [Group] 
    order by Age desc) 
    from yourtable)`
    
    
    `select Person, Age from CTE where RN = 1`
    
  13. ==============================

    13.당신은 또한 시도 할 수 있습니다

    당신은 또한 시도 할 수 있습니다

    SELECT * FROM mytable WHERE age IN (SELECT MAX(age) FROM mytable GROUP BY `Group`) ;
    
  14. ==============================

    14.이 예약 된 단어이기 때문에 나는 열 이름으로 그룹을 사용하지 않을 것입니다. 그러나 다음과 같은 SQL이 작동합니다.

    이 예약 된 단어이기 때문에 나는 열 이름으로 그룹을 사용하지 않을 것입니다. 그러나 다음과 같은 SQL이 작동합니다.

    SELECT a.Person, a.Group, a.Age FROM [TABLE_NAME] a
    INNER JOIN 
    (
      SELECT `Group`, MAX(Age) AS oldest FROM [TABLE_NAME] 
      GROUP BY `Group`
    ) b ON a.Group = b.Group AND a.Age = b.oldest
    
  15. ==============================

    15.이 방법은 다른 열을 기준으로 순위에 당신을 허용하고, 다른 데이터를 부수고하지 않는 이점이있다. 먼저 가장 무거운 목록, 당신이 항목에 대한 열 목록 주문하려고하는 상황에서 매우 유용합니다.

    이 방법은 다른 열을 기준으로 순위에 당신을 허용하고, 다른 데이터를 부수고하지 않는 이점이있다. 먼저 가장 무거운 목록, 당신이 항목에 대한 열 목록 주문하려고하는 상황에서 매우 유용합니다.

    출처 : http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

    SELECT person, group,
        GROUP_CONCAT(
            DISTINCT age
            ORDER BY age DESC SEPARATOR ', follow up: '
        )
    FROM sql_table
    GROUP BY group;
    
  16. ==============================

    16.테이블 이름이 사람들하자

    테이블 이름이 사람들하자

    select O.*              -- > O for oldest table
    from people O , people T
    where O.grp = T.grp and 
    O.Age = 
    (select max(T.age) from people T where O.grp = T.grp
      group by T.grp)
    group by O.grp; 
    
  17. ==============================

    17.ID (모든 열) MYTABLE에서 필요한 경우

    ID (모든 열) MYTABLE에서 필요한 경우

    SELECT
        *
    FROM
        mytable
    WHERE
        id NOT IN (
            SELECT
                A.id
            FROM
                mytable AS A
            JOIN mytable AS B ON A. GROUP = B. GROUP
            AND A.age < B.age
        )
    
  18. ==============================

    18.이것은 내가 MySQL의에서 그룹 당 N 최대 행을 얻고 어떻게

    이것은 내가 MySQL의에서 그룹 당 N 최대 행을 얻고 어떻게

    SELECT co.id, co.person, co.country
    FROM person co
    WHERE (
    SELECT COUNT(*)
    FROM person ci
    WHERE  co.country = ci.country AND co.id < ci.id
    ) < 1
    ;
    

    작동 방식 :

    전체 예 여기 :

    그룹 당 n 개의 최대 값을 선택 MYSQL

  19. from https://stackoverflow.com/questions/12102200/get-records-with-max-value-for-each-group-of-grouped-sql-results by cc-by-sa and MIT license