[SQL] SQL은 : 행을 선택하는 열 값은 이전 행 변경된 곳
SQLSQL은 : 행을 선택하는 열 값은 이전 행 변경된 곳
의 난이 (MySQL의) 데이터베이스가 있다고 가정 해 봅시다 증가 타임 스탬프으로 분류 :
Timestamp System StatusA StatusB
2011-01-01 A Ok Ok
2011-01-02 B Ok Ok
2011-01-03 A Fail Fail
2011-01-04 B Ok Fail
2011-01-05 A Fail Ok
2011-01-06 A Ok Ok
2011-01-07 B Fail Fail
StatusA가 해당 시스템의 이전 행에서 변경할 경우 어떻게 행을 선택합니까? StatusB은 (난 단지 StatusA이 변경되지 않는 각 시스템에 대한 많은 연속 행이있을 수 있음을 설명하기 위해이 질문에 보여) 문제가되지 않습니다. 위의 예에서, 쿼리는 행 2011-01-03, 2011-01-06, 2011-01-07 (StatusA은과 SystemA 위해 2011-01-01 및 2011-01-03 사이에서 변화)를 호출한다.
쿼리는 테이블 만개의 레코드를 갖는 신속하게 실행해야한다.
감사
해결법
-
==============================
1.
SELECT a.* FROM tableX AS a WHERE a.StatusA <> ( SELECT b.StatusA FROM tableX AS b WHERE a.System = b.System AND a.Timestamp > b.Timestamp ORDER BY b.Timestamp DESC LIMIT 1 )
하지만 당신은 (시스템, 타임 스탬프)에 인덱스뿐만 아니라이 (시도 할 수 있습니다 :
SELECT System, Timestamp, StatusA, StatusB FROM ( SELECT (@statusPre <> statusA AND @systemPre=System) AS statusChanged , System, Timestamp, StatusA, StatusB , @statusPre := StatusA , @systemPre := System FROM tableX , (SELECT @statusPre:=NULL, @systemPre:=NULL) AS d ORDER BY System , Timestamp ) AS good WHERE statusChanged ;
-
==============================
2.
select a.Timestamp, a.System, a.StatusA, a.StatusB from tableX as a cross join tableX as b where a.System = b.System and a.Timestamp > b.Timestamp and not exists (select * from tableX as c where a.System = c.System and a.Timestamp > c.Timestamp and c.Timestamp > b.Timestamp ) and a.StatusA <> b.StatusA;
코멘트를 해결하는 업데이트 : 왜 내부 크로스 조인을 대신 조인을 사용하지?
문제는 MySQL의 솔루션을 요청합니다. 문서에 따르면 :
이 수단이 중 하나가 작동 할 조인.
조건 a.System = b.System은 아마 INNER이 경우에 더 좋은 것 조인을 사용하도록 '에 가입하는 방법 테이블'카테고리에 해당.
모두 동일한 결과를 생성하기 때문에, 차이는 성능에있을 수 있습니다. 그들이 가입을 할 인덱스 나 해시를 사용하는지 여부 - 빠른 I는 내부적으로 구현 조인있는 방법을 알 필요가있을 것이다라고합니다.
-
==============================
3.사용 ROWNUM
사용 ROWNUM
나는 20000 행에 0.05 초있어
select a1.* from (select rownum R_NUM, TIMESTAMP, System, StatusA from TableX) a1 join (select rownum R_NUM, TIMESTAMP, SYSTEM, STATUSA from TABLEX) a2 on a1.R_NUM = a2.R_NUM+1 where a1.system = a2.system and a1.StatusA != a2.StatusA
-
==============================
4.여기에 비슷한 논리를 갖는 약간 짧은 버전입니다. 나는 그것을 효율적 확신 너무 자주 테스트했습니다; 그것은 상관 하위 쿼리 (WHERE NOT EXISIS)를 제거 주로 때문이다.
여기에 비슷한 논리를 갖는 약간 짧은 버전입니다. 나는 그것을 효율적 확신 너무 자주 테스트했습니다; 그것은 상관 하위 쿼리 (WHERE NOT EXISIS)를 제거 주로 때문이다.
"C"가 있는지 b는 바로 아래에 있음이 확인에 - 그것은합니다 (NULL 테스트를 통해) (사이) C 찾을 수 없습니다 말했다.
SELECT a.Timestamp, a.System, a.StatusA, a.StatusB FROM tableX AS a JOIN tableX AS b ON a.System = b.System AND a.Timestamp > b.Timestamp LEFT JOIN tableX AS c ON a.System = b.System AND a.Timestamp > c.Timestamp AND b.Timestamp < c.Timestamp WHERE c.System IS NULL AND a.StatusA <> b.StatusA;
-
==============================
5.에고의 대답은 하나의 작은 변화에 MSSQL에서 날 위해 일했습니다. 와 ROWNUM 문을 대체했다 :
에고의 대답은 하나의 작은 변화에 MSSQL에서 날 위해 일했습니다. 와 ROWNUM 문을 대체했다 :
select row_number () over (order by TIMESTAMP) as R_NUM, ...
-
==============================
6.
SELECT a.* FROM (select row_number() over (partition by System order by Timestamp asc) as aRow, Timestamp, System, StatusA, StatusB from tableX) as a left join (select row_number() over (partition by System order by Timestamp asc) as bRow, Timestamp, System, StatusA, StatusB from tableX) as b on a.aRow = b.bRow + 1 and a.System = b.System where (a.StatusA != b.StatusA or b.StatusA is null)
값이 다른 곳은 첫 번째 행과 행을 반환합니다.
from https://stackoverflow.com/questions/6560000/sql-selecting-rows-where-column-value-changed-from-previous-row by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 XSD 파일에서 데이터베이스 테이블을 만들 수 있습니까? (0) | 2020.04.06 |
---|---|
[SQL] 얼마나 많은 행이 데이터베이스에 너무 많은입니까? (0) | 2020.04.06 |
[SQL] 열 함유 쉼표의 값이 값을 구분 어디에 (0) | 2020.04.06 |
[SQL] 표 SQL 서버에 XML을 변환 (0) | 2020.04.06 |
[SQL] 테이블의 한 필드를 기준으로 Linq에있는 고유 (0) | 2020.04.06 |