[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.이 같은? 자체 테이블을 가입하고, 높은 신호가 발견되는 행을 제외 할 수 있습니다.
이 같은? 자체 테이블을 가입하고, 높은 신호가 발견되는 행을 제외 할 수 있습니다.
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.당신은 그룹 현명한 최대 / 최소 작업을하고 있습니다. 그것은 쉽게 할 수 있어야 뭔가 느낌,하지만 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.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.
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.
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.우리는 자기 조인을 사용 할 수 있습니다
우리는 자기 조인을 사용 할 수 있습니다
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.
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.
SELECT * FROM StatusTable WHERE Signal IN ( SELECT A.maxSignal FROM ( SELECT ID, MAX(Signal) AS maxSignal FROM StatusTable GROUP BY ID ) AS A );
-
==============================
9.고르다 신분증, max_signal, 소유자, ownerId FROM ( 테이블 max_signal 같이 * (신호 DESC 의해 ID 순서에 의한 분할) 위에 랭크 ()를 선택 ) 여기서 max_signal = 1;
고르다 신분증, max_signal, 소유자, ownerId FROM ( 테이블 max_signal 같이 * (신호 DESC 의해 ID 순서에 의한 분할) 위에 랭크 ()를 선택 ) 여기서 max_signal = 1;
from https://stackoverflow.com/questions/755918/simple-query-to-grab-max-value-for-each-id by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게에만 시간을 저장합니다; 하지 날짜와 시간? (0) | 2020.03.29 |
---|---|
[SQL] 외래 키 참조가 아닌 고유 인덱스 할 수 있습니까? (0) | 2020.03.29 |
[SQL] 준비된 문을 통해 INSERT INTO와 PDO [폐쇄] (0) | 2020.03.29 |
[SQL] SQL 계산에서 별칭을 사용하여 (0) | 2020.03.29 |
[SQL] 왜 MySQL은 FULL OUTER에 구문 오류가 JOIN보고는 무엇입니까? (0) | 2020.03.28 |