복붙노트

[SQL] 각 ID에 대한 잡아 최대 값에 대한 간단한 쿼리

SQL

각 ID에 대한 잡아 최대 값에 대한 간단한 쿼리

OK 나는이 같은 테이블이 있습니다 :

ID     Signal    Station    OwnerID
111     -120      Home       1
111     -130      Car        1
111     -135      Work       2
222     -98       Home       2
222     -95       Work       1
222     -103      Work       2

이는 같은 날에 대한 모든 것입니다. 난 그냥 쿼리는 각 ID에 대해 최대 신호를 반환해야합니다

ID    Signal    Station    OwnerID
111   -120      Home        1
222   -95       Work        1

나는 MAX ()와 역 OwnerID 각 레코드에 대해 서로 다른 존재로 집계 놨 최대를 사용했습니다. 나는이 가입 할 필요가 있습니까?

해결법

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

    1.이 같은? 자체 테이블을 가입하고, 높은 신호가 발견되는 행을 제외 할 수 있습니다.

    이 같은? 자체 테이블을 가입하고, 높은 신호가 발견되는 행을 제외 할 수 있습니다.

    select cur.id, cur.signal, cur.station, cur.ownerid
    from yourtable cur
    where not exists (
        select * 
        from yourtable high 
        where high.id = cur.id 
        and high.signal > cur.signal
    )
    

    이것은 각각의 가장 높은 신호에 대한 하나 개의 행을 나열합니다, 그래서 ID 당 여러 행이있을 수 있습니다.

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

    2.당신은 그룹 현명한 최대 / 최소 작업을하고 있습니다. 그것은 쉽게 할 수 있어야 뭔가 느낌,하지만 SQL 년에는 aggravatingly되지 않습니다 : 이것은 일반적인 함정이다.

    당신은 그룹 현명한 최대 / 최소 작업을하고 있습니다. 그것은 쉽게 할 수 있어야 뭔가 느낌,하지만 SQL 년에는 aggravatingly되지 않습니다 : 이것은 일반적인 함정이다.

    많은 상황에서 하위 최적 대부분의이 문제에 대한 접근 방법 (모두 표준 ANSI 및 공급 업체 특정)이있다. 일부는 당신에게 여러 행을 줄 것이다 때 하나 이상의 행을 공유 동일한 최대 / 최소 값; 일부는하지 않습니다. 또한 그룹의 수가 적은 테이블에서 일부 작업; 다른 그룹 당 작은 행 그룹 더 많은 수의 더 효율적입니다.

    다음은 일반적인 것들의 일부에 대한 논의는 (MySQL은 바이어스하지만 일반적으로 적용)입니다. 개인적으로 내가 알고있는 경우에는 다수의 최대 값이없는 (또는 그들을 것에 대해 걱정하지 않는다) 나는 종종 다른 누구도 아직 없기 때문에 내가 게시합니다 널 왼쪽 자체 조인 방법으로 경향이있다 :

    SELECT reading.ID, reading.Signal, reading.Station, reading.OwnerID
    FROM readings AS reading
    LEFT JOIN readings AS highersignal
        ON highersignal.ID=reading.ID AND highersignal.Signal>reading.Signal
    WHERE highersignal.ID IS NULL;
    
  3. ==============================

    3.SQL-92 (Quassnoi에 의해 사용되는 OLAP 작업을 사용하지 않는)이, 당신이 사용할 수있는 고전에서 :

    SQL-92 (Quassnoi에 의해 사용되는 OLAP 작업을 사용하지 않는)이, 당신이 사용할 수있는 고전에서 :

    SELECT g.ID, g.MaxSignal, t.Station, t.OwnerID
      FROM (SELECT id, MAX(Signal) AS MaxSignal
              FROM t
              GROUP BY id) AS g
           JOIN t ON g.id = t.id AND g.MaxSignal = t.Signal;
    

    (체크되지 않은 구문은, 테이블은 't'가정합니다.)

    FROM 절 서브 쿼리는 각 ID의 최대 신호 값을 식별; 메인 테이블에서 해당 데이터 열로하는 콤바인 가입.

    NB :이 모두 동일한 신호 강도를 가지고 특정 ID에 대한 여러 항목이며, 그 강도는 MAX () 인 경우에, 당신이 그 ID에 대한 몇 가지 출력 행을 얻을 것이다.

    IBM 인포믹스 다이나믹 서버 11.50.FC3 솔라리스 10에서 실행에 대한 테스트 :

    + CREATE TEMP TABLE signal_info
    (
        id      INTEGER NOT NULL,
        signal  INTEGER NOT NULL,
        station CHAR(5) NOT NULL,
        ownerid INTEGER NOT NULL
    );
    + INSERT INTO signal_info VALUES(111, -120, 'Home', 1);
    + INSERT INTO signal_info VALUES(111, -130, 'Car' , 1);
    + INSERT INTO signal_info VALUES(111, -135, 'Work', 2);
    + INSERT INTO signal_info VALUES(222, -98 , 'Home', 2);
    + INSERT INTO signal_info VALUES(222, -95 , 'Work', 1);
    + INSERT INTO signal_info VALUES(222, -103, 'Work', 2);
    + SELECT g.ID, g.MaxSignal, t.Station, t.OwnerID
      FROM (SELECT id, MAX(Signal) AS MaxSignal
                FROM signal_info
                GROUP BY id) AS g
          JOIN signal_info AS t  ON g.id = t.id AND g.MaxSignal = t.Signal;
    
    111     -120    Home    1
    222     -95     Work    1
    

    나는이 테스트 테이블 Signal_Info 이름 -하지만 정답을 생산하는 것 같다. 이 단지 쇼 표기법을 지원하는 적어도 하나의 DBMS가 있다는 것을. 사용중인 버전 - 그러나, 나는 조금 MS SQL 서버는하지 않는 것이 놀라는 무엇입니까?

    그것은 SQL 질문은 테이블 이름없이 제출되는 빈도 나를 놀라게 중단하지 마십시오.

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

    4.

    
    with tab(id, sig, sta, oid) as
    (
    select 111 as id, -120 as signal, 'Home' as station, 1 as ownerId union all
    select 111, -130, 'Car',  1 union all
    select 111, -135, 'Work', 2 union all
    select 222, -98, 'Home',  2 union all
    select 222, -95, 'Work',  1 union all
    select 222, -103, 'Work', 2
    ) ,
    tabG(id, maxS) as
    (
       select id, max(sig) as sig from tab group by id
    )
    select g.*, p.* from tabG g
    cross apply ( select  top(1) * from tab t where t.id=g.id order by t.sig desc ) p
    
    
  5. ==============================

    5.

    WITH q AS
             (
             SELECT  c.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY signal DESC) rn
             FROM    mytable
             )
    SELECT   *
    FROM     q
    WHERE    rn = 1
    

    이것은 주어진 ID 용 MAX (신호)의 중복이있는 경우에도 하나 개의 행을 반환한다.

    (ID, 신호)에 인덱스를 갖는 것은 크게이 쿼리를 향상시킬 수 있습니다.

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

    6.우리는 자기 조인을 사용 할 수 있습니다

    우리는 자기 조인을 사용 할 수 있습니다

    SELECT  T1.ID,T1.Signal,T2.Station,T2.OwnerID
    FROM (select ID,max(Signal) as Signal from mytable group by ID) T1
    LEFT JOIN mytable T2
    ON T1.ID=T2.ID and T1.Signal=T2.Signal;
    

    또는 당신은 또한 다음과 같은 쿼리를 사용할 수 있습니다

    SELECT t0.ID,t0.Signal,t0.Station,t0.OwnerID 
    FROM mytable t0 
    LEFT JOIN mytable t1 ON t0.ID=t1.ID AND t1.Signal>t0.Signal 
    WHERE t1.ID IS NULL;
    
  7. ==============================

    7.

    select a.id, b.signal, a.station, a.owner from 
    mytable a
    join 
    (SELECT ID, MAX(Signal) as Signal FROM mytable GROUP BY ID) b
    on a.id = b.id AND a.Signal = b.Signal 
    
  8. ==============================

    8.

    SELECT * FROM StatusTable
    WHERE Signal IN (
        SELECT A.maxSignal FROM
        (
            SELECT ID, MAX(Signal) AS maxSignal
            FROM StatusTable
            GROUP BY ID
        ) AS A
    );
    
  9. ==============================

    9.고르다  신분증,  max_signal,  소유자,  ownerId FROM (   테이블 max_signal 같이 * (신호 DESC 의해 ID 순서에 의한 분할) 위에 랭크 ()를 선택 ) 여기서 max_signal = 1;

    고르다  신분증,  max_signal,  소유자,  ownerId FROM (   테이블 max_signal 같이 * (신호 DESC 의해 ID 순서에 의한 분할) 위에 랭크 ()를 선택 ) 여기서 max_signal = 1;

  10. from https://stackoverflow.com/questions/755918/simple-query-to-grab-max-value-for-each-id by cc-by-sa and MIT license