복붙노트

[SQL] 그것은 하나의 UPDATE SQL 문으로 여러 업데이트를 수행 할 수 있습니까?

SQL

그것은 하나의 UPDATE SQL 문으로 여러 업데이트를 수행 할 수 있습니까?

하자 내가 열 ID와 제목 테이블 TBL을 말한다. 나는 제목의 컬럼의 모든 값을 변경해야합니다 :

지금, 나는이 UPDATE 문을 수행하고 있습니다 :

UPDATE tbl SET title='a1' WHERE title IN ('a-1', 'a.1')
UPDATE tbl SET title='b1' WHERE title IN ('b-1', 'b.1')

이 테이블이 작은 경우, 모든 문제에 있지, 그리고에서 하나의 문이 완료 적은 초 이상 및 만 실행하는 데 몇 문이 필요합니다.

나는 (약 90 초에서 하나 개의 문장이 완료)를 처리 할 수있는 큰 테이블이, 그리고 업데이트의 거대한 숫자가 수행해야 - 당신은 아마 그것을 guested.

그래서, 일단은 테이블을 스캔 할 수 있도록 업데이트를 병합 할 수 있습니까? 아니면,이 같은 상황에 대처하기 위해 더 나은 방법이있다.

편집 : 참고, 실제 데이터는 내가 함께 일하고 있어요 내가 수행해야 할 데이터에 대한 변경 사항은 정말없는 간단합니다 것을 - 사용자 데이터 문자열이 더 이상 그들이 어떤 패턴을 따르지 않는 (그것이 어떠한 가정도 그렇게 만들 수 있습니다 - 그것은) 아무것도 할 수있다.

해결법

  1. ==============================

    1.새 값의 각 매핑의 수백이있을 수있는 일반적인 경우에, 당신은 과거와 현재 값을 별도의 테이블을 만들 것입니다, 다음 UPDATE 문에 그것을 사용합니다. SQL의 한 방언에서 :

    새 값의 각 매핑의 수백이있을 수있는 일반적인 경우에, 당신은 과거와 현재 값을 별도의 테이블을 만들 것입니다, 다음 UPDATE 문에 그것을 사용합니다. SQL의 한 방언에서 :

    CREATE TEMP TABLE mapper (old_val CHAR(5) NOT NULL, new_val CHAR(5) NOT NULL);
    ...multiple inserts into mapper...
    INSERT INTO mapper(old_val, new_val) VALUES('a.1', 'a1');
    INSERT INTO mapper(old_val, new_val) VALUES('a-1', 'a1');
    INSERT INTO mapper(old_val, new_val) VALUES('b.1', 'b1');
    INSERT INTO mapper(old_val, new_val) VALUES('b-1', 'b1');
    ...etcetera...
    
    UPDATE tbl
       SET title = (SELECT new_val FROM mapper WHERE old_val = tbl.title)
       WHERE title IN (SELECT old_val FROM mapper);
    

    모두 선택 문은 매우 중요하다. 에 첫 번째로 상관 하위 쿼리입니다 (반드시 빨리,하지만 빠른 매퍼 테이블 행의 수천이있는 경우 대안의 대부분 이상) 매핑 테이블에서 새 값을 가져옵니다이 그 이전 값에 해당합니다. 매핑 테이블에 값이 행만이 변형되어 제 보장하지만; 그렇지 않으면 제목이 매핑 항목없이 해당 행에 null로 설정 (그 당신이 시작하기 전에 확인을했던 기록했다)됩니다 이것은 매우 중요합니다.

    몇 가지 대안의 경우, CASE 작업은 OK입니다. 당신이 수행 할 수있는 매핑의 수백 또는 수천 또는 수백만이있는 경우 그러나, 당신은 당신의 DBMS에서 SQL 문 길이의 한계를 초과 할 가능성이 높다.

  2. ==============================

    2.당신은 하나 개의 문장 및 사례 문의 번호를 사용할 수 있습니다

    당신은 하나 개의 문장 및 사례 문의 번호를 사용할 수 있습니다

    update tbl
      set title = 
        case
          when title in ('a-1', 'a.1') then 'a1'
          when title in ('b-1', 'b.1') then 'b1'
          else title
        end
    

    물론,이 모든 레코드에 쓰기의 원인이됩니다, 당신이 변경하려는 경우에만 행을 필터링 할 수 있도록 인덱스, 그것은 문제가 될 수 있습니다 :

    update tbl
      set title = 
        case
          when title in ('a-1', 'a.1') then 'a1'
          when title in ('b-1', 'b.1') then 'b1'
          else title
        end
    where
      title in ('a.1', 'b.1', 'a-1', 'b-1')
    

    즉 테이블에 쓰기의 수를 줄일 것입니다.

  3. ==============================

    3.조나단의 대답의 오프 근무.

    조나단의 대답의 오프 근무.

    UPDATE tbl
       SET title = new_val
    FROM mapper
    WHERE title IN (SELECT old_val FROM mapper)
         AND mapper.old_val = tbl.title;
    

    매퍼 테이블에 읽고 자신의 초기 버전은 많은 수를 필요로한다.

  4. ==============================

    4.변형에 귀하의 예를 단순하게하는 경우, 당신은 문자열 조작의 조금으로 업데이트를 할 수 :

    변형에 귀하의 예를 단순하게하는 경우, 당신은 문자열 조작의 조금으로 업데이트를 할 수 :

    UPDATE tbl 
    SET title = left(title, 1) + right(title, 1) 
    WHERE title IN ('a-1', 'a.1', 'b-1', 'b.1')
    

    당신을 위해 그 일 싶습니다 뭔가?

  5. ==============================

    5.또는

    또는

       Update Table set 
         title = Replace(Replace(title, '.', ''), '-', '')
       Where title Like '[ab][.-]1'
    
  6. from https://stackoverflow.com/questions/412101/is-it-possible-to-perform-multiple-updates-with-a-single-update-sql-statement by cc-by-sa and MIT license