2013-03-15 3 views
0

고객 테이블의 '이름'필드의 익명화를 시도하고 있습니다. 모든 레코드의 '이름'을 다음 레코드의 고객 이름으로 바꾸고 싶습니다. (나는 알고있다 : 그것은 정말로 익명이 아니지만 'name'과 'customerId'는 그 이후에 일치하지 않는다.) 내 생각에는 충분하다.Oracle SQL - 데이터베이스 필드를 다음 레코드의 내용으로 업데이트하십시오.

나는 이것을 시도했지만 ORA-01747 오류가 발생한다.

UPDATE Customer A 
    SET NAME = 
      (SELECT NAME 
      FROM Customer 
      WHERE ROWNUM = A.ROWNUM + 1) 

무엇이 잘못 되었나요? 어떻게 모든 'name'필드를 테이블의 다음 'name'필드의 내용으로 업데이트 할 수 있습니까?

+0

시도하려는 작업을 수행하려면 자체 조인을 수행해야합니다. 또한 테이블의 마지막 행과 경쟁해야합니다. 그렇게 말하면서, 당신의 목표를 성취 할 수있는 더 좋은 방법이있을 것입니다. 나는 내 머리 꼭대기에서 어떤 것도 생각할 수 없다. –

답변

0

모두 섞어 라 !!!

merge into Customer dest 
using (
    select r, name from 
    (select name, row_number() over (order by dbms_random.value) n from Customer) 
    join (select rowid r, rownum n from Customer) using(n) 
) src 
on (dest.rowid = src.r) 
when matched then update set 
    dest.name = src.name; 
+0

안녕하세요 Egor, 멋진 진술입니다. 정말 잘 작동합니다. 고맙습니다! – wildewutz

+0

이름이 동일한 순서로 떨어지면 이름 자체에 할당되는 작은 결과 집합이있을 수 있습니다. –

1

ROWNUM은 의사 열이며 데이터와 함께 저장되지 않으며 결과 집합의 일부입니다. 또한 일반적으로 관계형 데이터베이스에는 행 순서 개념이 없습니다.

우리는 아마 그것을 할 미봉책 방법을 사용할 수 있습니다, 대신, 당신은 단지 대신 같은 것을 할 수 없었 : 오라클에서

UPDATE CUSTOMER SET NAME = DBMS_RANDOM.STRING('a', 10); 

을,이 10 숫자의 임의의 문자열로 모든 고객을 업데이트 자릿수.

-2

이것은 작동 할 수는 있지만 테스트되지 않았습니다.

UPDATE Customer A 
    SET NAME = 
      (SELECT NAME 
      FROM Customer 
      WHERE ROWNUM = (SELECT (A.ROWNUM + 1)) 
0

LEAD()를 사용해야합니다.

'a_horse_with_no_name의 의견에 따라 수정 : ENAME과 같은 LEAD (SAL, 1, 샐)

UPDATE emp_test a 
    SET sal = 
(
    SELECT LEAD(sal, 1, sal) OVER (ORDER BY sal) AS sal_next 
    FROM scott.emp b 
    WHERE a.empno = b.empno 
) 
/

:

SELECT empno, ename, job, sal, 
     LEAD(ename, 1, ename) OVER (ORDER BY ename) AS name_next 
    FROM scott.emp 
/

EMPNO ENAME JOB  SAL NAME_NEXT 
-------------------------------------------- 
7876 ADAMS CLERK  1100 ALLEN 
7499 ALLEN SALESMAN 1600 BLAKE 
7698 BLAKE MANAGER  2850 CLARK 
7782 CLARK MANAGER  2450 FORD 
.... 
7844 TURNER SALESMAN 1500 WARD 
7521 WARD  SALESMAN 1250 WARD 

이 작동하지 않습니다 :

SELECT * FROM scott.emp 
    WHERE ROWNUM = 5 
/

그러나 이것은 :

SELECT * FROM scott.emp 
WHERE ROWNUM <= 5 
/
+1

NVL은 꼭 필요한 것은 아닙니다. 'lead()'함수에 "default"값을 제공 할 수 있습니다 :'lead (ename, 1, ename)' –

+0

@a_horse_with_no_name - 감사합니다. 나는 그것을 놓쳤다. – Art

관련 문제