2011-09-09 4 views
2

여기가 계약입니다. 데이터가있는 테이블이 있습니다. 특정 필드를 기반으로 행 발생과 함께 필드를 채울 필요가 있습니다. 나는 한 행을 가지고 있을지도 모릅니다. 나는 10을 가질 것입니다. 그 숫자를 채워야합니다. 나는 rownumber()를 사용하여 select에서 숫자가 무엇인지 판단했다. 그러나 테이블을 업데이트하는 것은 문제가되었습니다. 조인을 시도했는데, tablename과 select, then update. 아무것도 효과가 없습니다.여러 행으로 Oracle에서 row_number()를 사용하여 업데이트

이 코드 :

update Rptdata 
SET c98 = (SELECT R from 
       (select rs1.c1, rs1.c5,rs1.c3, 
       row_number() over(partition by rs1.c1,0, rs1.c5,rs1.c3 order by rs1.c1,rs1.c5,rs1.c3 desc) as R 
       from Rptdata rs1 
       where rs1.c1 = c1 
       and rs1.c5 = c5 
       and rs1.c3 = c3 
     --  and rs1.c6 = c6 
     --  and rs1.c7 = c7 
     --  and rs1.c8 = c8 
     --  and rs1.c9 = c9 
       and rs1.program_name = 'INTERNAL' 
       AND rs1.program_id=030911 
       AND (rs1.c6 IS NULL 
       or rs1.c8 IS NULL 
       or rs1.c9 IS NULL) 
       and rs1.c28 IS NULL 
       ) 
     ) 
WHERE program_name = 'INTERNAL' 
AND program_id=030911 
AND (c6 IS NULL 
or c8 IS NULL 
or c9 IS NULL) 
and c28 IS NULL 

오류 ORA-01427를 생산 : 단일 행 부질의는 하나 개 이상의 행을 반환합니다. 나는 내가 원하는 것이라고 생각한다. 나는 주석을 제거하고 - rs1.c6 = c6 그리고 187 개의 행을 업데이트한다고 알려줍니다. 커밋 한 다음 해당 187 행의 선택 실행하고 c98에 아무것도 없습니다.

답변

4

문제는 row_number을 얻으려면 전체 하위 쿼리를 하나의 세트로 처리해야하지만 원하는 결과를 얻으려면 하나의 레코드로 축소해야합니다. 각 행을 업데이트하십시오. 이것이 update 엄격 가능하지만, 그것은 (당신이 10g를 사용하는 가정)이 시나리오에 merge를 사용하는 것이 훨씬 더 간단합니다 :

MERGE INTO rptdata rp 
USING  (SELECT ROW_NUMBER() OVER (PARTITION BY rs1.c1, 0, rs1.c5, rs1.c3 
             ORDER BY rs1.c1, rs1.c5, rs1.c3 DESC) AS r 
      FROM rptdata rs1 
      WHERE rs1.program_name = 'INTERNAL' 
       AND rs1.program_id = 030911 
       AND (rs1.c6 IS NULL OR rs1.c8 IS NULL OR rs1.c9 IS NULL) 
       AND rs1.c28 IS NULL) rs 
ON   (rs.c1 = rp.c1 AND rs.c5 = rp.c5 AND rs.c3 = rp.c3) 
WHEN MATCHED THEN 
    UPDATE SET 
     c98 = rs.r 
     WHERE  program_name = 'INTERNAL' 
      AND program_id = 030911 
      AND (c6 IS NULL OR c8 IS NULL OR c9 IS NULL) 
      AND c28 IS NULL 
덧붙여

, 당신은 제공되는 쿼리가 멀리하지 않습니다 떨어져서. 위에서 설명한대로 row_number으로 전체 세트를 가져온 다음 업데이트되는 각 행에 필요한 개별 레코드를 필터링해야합니다. 이를 수행하려면 조인 조건을 외부 쿼리로 이동해야합니다.

UPDATE rptdata 
SET c98 = 
      (SELECT r 
      FROM (SELECT rs1.c1, 
          rs1.c5, 
          rs1.c3, 
          ROW_NUMBER() OVER (PARTITION BY rs1.c1, 0, rs1.c5, rs1.c3 
              ORDER BY rs1.c1, rs1.c5, rs1.c3 DESC) 
          AS r 
        FROM rptdata rs1 
        WHERE rs1.program_name = 'INTERNAL' 
         AND rs1.program_id = 030911 
         AND (rs1.c6 IS NULL OR rs1.c8 IS NULL OR rs1.c9 IS NULL) 
         AND rs1.c28 IS NULL) 
      WHERE rs1.c1 = c1 AND rs1.c5 = c5 AND rs1.c3 = c3) 
WHERE program_name = 'INTERNAL' 
    AND program_id = 030911 
    AND (c6 IS NULL OR c8 IS NULL OR c9 IS NULL) 
    AND c28 IS NULL 
관련 문제