2017-02-14 8 views
3

이 문제의 경우 - Shuffle a column between rows -이 경우에 적용해야하는 새로운 조건 : 이름이 남성, 여성 또는 알 수없는 성별을 보장해야합니다.행에있는 Oracle Shuffle 열

그래서 테이블의 이름은 gender입니다. 같은 성별로 부름을 섞어 야해.

나는이 시도했지만, 어떤 경우에는 내가 성을 사용할 수 없음을 성별

merge into original_table o 
    using (
    with 
     helper (id, gender, rn, rand_rn) as (
      select id, 
        gender, 
        row_number() over (order by id), 
        row_number() over (order by dbms_random.value()) 
      from original_table 
     ) 
    select ot.name, ot.gender, h2.id 
    from original_table ot inner join helper h1 on (ot.id = h1.id and ot.gender = h1.gender) 
          inner join helper h2 on h1.rand_rn = h2.rn 
) p 
on (o.id = p.id) 
when matched then update set o.name = p.name 
; 

그리고 경우를 보장 할 수 없습니다이 병합 아무것도 업데이트되지, 예를 들어 회사의 이름 (null 값입니다) .

이 쿼리를 3 가지 병합 문으로 분리 할 수 ​​있습니다. 내가 가진 각 성별마다 하나씩. 그러나 나는 더 나은 간단하게 성명을 찾고 있습니다. 왜냐하면 나는 다른 상황과 조건으로 동일한 솔루션을 적용해야하기 때문입니다. 감사합니다. .

편집 : 샘플 데이터

ID  GENDER NAME                         
3721  M  MARK 
3722  M  JUSTIN 
3723  F  RUTH 
3724  F  MARY 
3725  F  ANNE 
4639    CAMPANY SA                    
4640  M  JOHN 
4641  M  LUCAS 
4642    COMPANY HOLDER SA 

한 가지 가능한 솔루션 :

ID  GENDER NAME                         
3721  M  LUCAS 
3722  M  JOHN 
3723  F  MARY 
3724  F  ANNE 
3725  F  RUTH 
4639    CAMPANY HOLDER SA                    
4640  M  MARK 
4641  M  JUSTIN 
4642    COMPANY SA 
+0

당신은 데이터의 샘플 및 원하는 결과를 보여줄 수 있습니까? –

+1

샘플 데이터가 추가되었습니다. 성별로 이름을 섞어 야해. – milheiros

+0

왜 이렇게해야하는지 궁금합니다. – BobC

답변

2

는 분석 기능에서와 JOIN 절에 PARTITION BY 절에 성별을 포함합니다. 일치시킬 기본 키가 없다면 ROWID 가상 컬럼을 사용할 수 있습니다.

오라클 설치 :

CREATE TABLE original_table (id, gender, name, company) AS 
SELECT 1, 'F', 'Alice', CAST(NULL AS VARCHAR2(20)) FROM DUAL UNION ALL 
SELECT 2, 'M', 'Bobby', 'ACME' FROM DUAL UNION ALL 
SELECT 3, 'F', 'Carol', 'XYZ' FROM DUAL UNION ALL 
SELECT 4, 'M', 'David', NULL FROM DUAL UNION ALL 
SELECT 5, 'M', 'Errol', 'ACME' FROM DUAL UNION ALL 
SELECT 6, 'F', 'Fiona', 'XYZ' FROM DUAL; 

업데이트 :

MERGE INTO original_table dst 
USING (
    WITH rnd (rid, rn, rnd_rn, gender, name) AS (
    SELECT ROWID, 
      ROW_NUMBER() OVER (PARTITION BY gender ORDER BY id), 
      ROW_NUMBER() OVER (PARTITION BY gender ORDER BY DBMS_RANDOM.VALUE), 
      gender, 
      name 
    FROM original_table 
) 
    SELECT o.rid, r.name 
    FROM rnd o INNER JOIN rnd r 
     ON ((o.gender = r.gender OR (o.gender IS NULL AND r.gender IS NULL)) 
      AND o.rn = r.rnd_rn) 
) 
ON (dst.ROWID = src.ROWID) 
WHEN MATCHED THEN 
    UPDATE SET name = src.name; 

출력 :

SELECT * FROM original_table; 

ID G NAME COMPANY 
-- - ----- ------- 
1 F Fiona 
2 M David ACME 
3 F Alice XYZ 
4 M Bobby 
5 M Errol ACME 
6 F Carol XYZ 
+0

위대한 MT0! 당신은 솔루션을 단순화합니다! 감사 – milheiros