ROWNUM이랑 ROW_NUMBER()에 대해 알아볼 예정인데요 둘의 차이가 뭐인지도 같이 예시로 다뤄보도록 하겠습니다!!
우선, ROWNUM 이건 FROM과 WHERE절을 읽고 그다음 조회된 값들에 번호를 부여하는 형식으로 되어 있습니다
SELECT ROWNUM, ENO,ENAME,DNO
FROM EMP
WHERE DNO IN ('01','10','20')
조회된 값에 1번부터 시작해서 번호가 부여된걸 확인이 가능합니다! 근데 여기서 문제점...!!!!! 바로바로 FROM, WHERE 절만 읽고 부여하다보니 ORDER BY를 현재 보여지는 조회와 다를 경우 ROWNUM은 엉망진창으로 보일 수가 있어요
SELECT ROWNUM, ENO,ENAME,DNO
FROM EMP
WHERE DNO IN ('01','10','20')
ORDER BY DNO
특히나 GROUP BY 절을 이용해서 부서별 인원에 순번을 정해주는 이런걸 만들어줄 경우에는 이렇게 ROWNUM이 되어 있으면 완전,, 망하는거죠
저는 ROWNUM을 잘 사용하지 않는 편이고, 사용해도 테이블에 있는 값과 거의 동일하게 INSERT 해줄때 가끔 사용하고 있습니다
INSERT INTO 테이블 A
SELECT B.a, B.b, '수정'
FROM 테이블 B
WHERE ROWNUM = 1
이런식으로 ROWNUM에서 1만 불러와서 동일하게 넣어주고 수정할 부분의 컬럼 값만 바꿔주는거죠 굳이 다른 컬럼의 값을 제가 직접 입력할 필요가 없어서 이 부분은 사용하실 때 효율적이세요!!
이번엔 ROW_NUMBER()에 대해 알아봅니다! ROW_NUMBER()는 OVER()과 함께 사용이 됩니다 형식은 ROW_NUMBER() OVER(PARTITION BY ~ ORDER BY ~) 입니다 *PARTITION BY는 GROUP BY와 동일하게 생각해주시면 됩니다!
만약 OVER를 사용하지 않으시게 된다면 ORA-30484:이 함수에 대한 윈도우 지정이 없습니다 라는 오류가 발생하게 돼요 OVER 내에는 ORDER BY는 단독으로 사용이 가능하나 PARTITION BY는 단독으로 사용이 불가능해보입니다 ORDER BY를 사용하라고 안내 메세지가 나오기 때문이죠!!
SELECT ROW_NUMBER() OVER(ORDER BY DNO), ENO,ENAME,DNO
FROM EMP
WHERE DNO IN ('01','10','20')
ORDER BY DNO
ORDER BY만 사용하였을 때 예시입니다 부서로 정렬된 상태로 번호가 부여된 것을 확인하실 수 있습니다!
이때 만약 부서별로 순번을 부여 하고 싶으실 경우에는 사용하지 않은 PARTITION BY를 사용해주시면 됩니다!
SELECT ROW_NUMBER() OVER(PARTITION BY DNO ORDER BY DNO), ENO,ENAME,DNO
FROM EMP
WHERE DNO IN ('01','10','20')
ORDER BY DNO
나같은 경우는 이런 오류가 발생한 원인은 이미 테이블에 데이터가 있는 상태에서 기본키 내 컬럼을 뺐더니 중복되는 데이터 값이 존재해서 불가능하였다.
예를들면 테이블 A가 방문일자, 방문시간, 이름 ... 이 런식으로 컬럼이 존재한다고 했을 때 기존에는 방문일자, 방문시간, 이름이 기본키 그룹에 해당하고, 방문일자, 방문시간이 새로운 기본키 그룹으로 만들려고 했을 때 테이블 내 방문일자, 방문시간이 동일한 데이터가 존재해서 오류가 발생하는 것이다!
그래서 기본키가 3개일때에서 갯수를 +1, +2하는건 오류가 발생하지 않으나 -1, -2 였을때는 오류가 발생하니 이점 유의해서 사용해주면 된다!!