최신 레코드를 제외한 모든 레코드를 삭제하시겠습니까?
일대일 관계의 DB 테이블이 두 개 있습니다.데이터는 다음과 같습니다.
select * from student, application
결과 집합:
+-----------+---------------+---------------------+
| StudentID | ApplicationID | ApplicationDateTime |
+-----------+---------------+---------------------+
| 1 | 20001 | 12 April 2011 |
| 1 | 20002 | 15 May 2011 |
| 2 | 20003 | 02 Feb 2011 |
| 2 | 20004 | 13 March 2011 |
| 2 | 20005 | 05 June 2011 |
+-----------+---------------+---------------------+
저는 가장 최근의 애플리케이션을 제외한 모든 애플리케이션을 삭제하고 싶습니다.다시 말해, 각 학생은 하나의 애플리케이션만 연결해야 합니다.위의 예를 사용하면 데이터는 다음과 같습니다.
+-----------+---------------+---------------------+
| StudentID | ApplicationID | ApplicationDateTime |
+-----------+---------------+---------------------+
| 1 | 20002 | 15 May 2011 |
| 2 | 20005 | 05 June 2011 |
+-----------+---------------+---------------------+
올바른 기록을 걸러내기 위해 DELETE 문을 구성하려면 어떻게 해야 합니까?
DELETE FROM student
WHERE ApplicationDateTime <> (SELECT max(ApplicationDateTime)
FROM student s2
WHERE s2.StudentID = student.StudentID)
의견에 대한 긴 토론을 고려할 때 다음 사항에 유의하십시오.
위의 명령문은 명령문이 실행되는 동안 테이블의 변경 사항에 관계없이 명령문 수준 읽기 일관성을 적절하게 구현하는 모든 데이터베이스에서 작동합니다.
표를 동시에 수정하더라도 올바르게 작동하는 데이터베이스:Oracle(이 질문에 대한 내용), Postgres, SAP HANA, Firebird(대부분 InnoDB를 사용하는 MySQL).모두 문이 시작된 시점에서 데이터의 일관된 보기를 보장하기 때문입니다.변경 내용<>로.<고객을 위해 아무것도 변경하지 않습니다(이 질문에 대한 Oracle 포함).
위에서 언급한 데이터베이스의 경우 팬텀 읽기 또는 반복할 수 없는 읽기는 단일 문 내에서가 아니라 여러 문 사이에서만 발생할 수 있기 때문에 문은 분리 수준의 영향을 받지 않습니다.
MVCC를 제대로 구현하지 않고 잠금에 의존하여 동시 쓰기 액세스를 관리하는 데이터베이스의 경우 테이블이 동시에 업데이트되면 실제로 잘못된 결과가 발생할 수 있습니다.다음을 사용하여 해결할 경우<아마도 필요할 것입니다.
사용할 수 있습니다.row_number()(또는)rank()또는dense_rank()아니면 심지어 그냥.rownum순서를 레코드에 적용한 다음 해당 순서를 사용하여 삭제할 항목을 결정합니다.이 경우, 다음과 같이 주문합니다.applicationdatetime desc각 학생의 가장 최근 날짜가 있는 응용 프로그램에 1:
select studentid, applicationid from (
select studentid, applicationid,
row_number() over (partition by studentid
order by applicationdatetime desc) as rn
from application
)
where rn = 1;
STUDENTID APPLICATIONID
---------- -------------
1 20002
2 20005
그런 다음 순위가 1보다 높은 모든 항목을 삭제할 수 있습니다. 그러면 중요한 레코드가 보존됩니다.
delete from application
where (studentid, applicationid) in (
select studentid, applicationid from (
select studentid, applicationid,
row_number() over (partition by studentid
order by applicationdatetime desc) as rn
from application
)
where rn > 1
);
3 rows deleted.
처음에는 그렇게 할 수 있습니다.
DELETE FROM [student]
or [application]
WHERE (studentid, applicationid) NOT IN (SELECT StudentID
,MAX(ApplicationID)
FROM student
,application
group by StudentID);
그러나 테이블에 있는 모든 레코드를 삭제하고 테이블에서 최대값을 선택하여 데이터(원하는 항목)를 삽입한 후 백업 테이블을 만들 수 있는 또 다른 솔루션이 있습니다.
언급URL : https://stackoverflow.com/questions/7238983/delete-all-records-except-the-most-recent-one
'programing' 카테고리의 다른 글
| 스프링 통합 테스트: 기본 리소스 위치를 검색할 수 없습니다. (0) | 2023.07.07 |
|---|---|
| 엔티티 관리자를 사용하는 경우 해당 이름에 대해 정의된 쿼리가 없습니다. (0) | 2023.07.07 |
| 사용자별 gitignore 파일을 만들 수 있습니까? (0) | 2023.07.07 |
| 연속적이지 않은 커밋 두 개를 제거하려면 어떻게 해야 합니까? (0) | 2023.07.07 |
| CSRF 보호가 Spring Security 6과 함께 작동하지 않음 (0) | 2023.07.07 |