populate columns based on 2 columns

前端 未结 1 1559
日久生厌
日久生厌 2021-01-25 16:54

Hoping someone can help me write an SQL script or function.

I have a data source which i want the function to go through and populate the relevant columns based on the

相关标签:
1条回答
  • 2021-01-25 17:17

    Oracle Setup:

    CREATE TABLE your_table (
      name  VARCHAR2(7)
            CHECK ( name IS NULL OR REGEXP_LIKE( name, '^[A-D](\+[A-D]){0,3}$', 'i' ),
      value VARCHAR2(200),
      A     VARCHAR2(50),
      B     VARCHAR2(50),
      C     VARCHAR2(50),
      D     VARCHAR2(50)
    );
    
    INSERT INTO your_table ( name, value, a, b, c, d )
      SELECT 'a+b+c+d', 'x2+x1+x3+x5', NULL, NULL, NULL, NULL FROM DUAL UNION ALL
      SELECT 'a+d+c',   'y7+y3+y4',    NULL, NULL, NULL, NULL FROM DUAL;
    

    Update Statement:

    MERGE INTO your_table dst
    USING (
      WITH splitstrings ( rid, name, value, col, val, lvl ) AS (
        SELECT ROWID,
               UPPER( name ),
               value,
               REGEXP_SUBSTR( UPPER( name ), '[^+]+', 1, 1 ),
               REGEXP_SUBSTR( value, '[^+]+', 1, 1 ),
               1
        FROM   your_table
        WHERE  name IS NOT NULL
        AND    value IS NOT NULL
      UNION ALL
        SELECT rid,
               name,
               value,
               REGEXP_SUBSTR( name, '[^+]+', 1, lvl + 1 ),
               REGEXP_SUBSTR( value, '[^+]+', 1, lvl + 1 ),
               lvl + 1
        FROM   splitstrings
        WHERE  lvl < LEAST(
                       REGEXP_COUNT( name, '[^+]+' ),
                       REGEXP_COUNT( value, '[^+]+' )
                     )
      )
      SELECT *
      FROM   ( SELECT rid, col, val FROM splitstrings )
      PIVOT  ( MAX( val ) FOR col IN ( 'A' AS a, 'B' AS b, 'C' AS c, 'D' AS d ) )
    ) src
    ON ( src.rid = dst.ROWID )
    WHEN MATCHED THEN
      UPDATE
        SET A = COALESCE( src.A, dst.A ),
            B = COALESCE( src.B, dst.B ),
            C = COALESCE( src.C, dst.C ),
            D = COALESCE( src.D, dst.D );
    

    Output:

    SELECT * FROM your_table;
    
    NAME    VALUE       A  B  C  D
    ------- ----------- -- -- -- --
    a+b+c+d x2+x1+x3+x5 x2 x1 x3 x5
    a+d+c   y7+y3+y4    y7    y4 y3
    

    Version 2:

    Oracle Setup:

    CREATE TABLE your_source (
      name  VARCHAR2(50),
      value VARCHAR2(50)
    );
    
    INSERT INTO your_source
      SELECT 'a+b+c+d', 'x2+x1+x3+x5' FROM DUAL UNION ALL
      SELECT 'a+d+c',   'y7+y3+y4'    FROM DUAL;
    
    CREATE TABLE your_destination (
    --  name  VARCHAR2(50),
    --  value VARCHAR2(50),
      A VARCHAR2(20),
      B VARCHAR2(20),
      C VARCHAR2(20),
      D VARCHAR2(20)
    );
    

    Insert Statement:

    INSERT INTO your_destination ( /* name, value, */ A, B, C, D )
      WITH splitstrings ( rid, name, value, col, val, lvl ) AS (
        SELECT ROWID,
               UPPER( name ),
               value,
               REGEXP_SUBSTR( UPPER( name ), '[^+]+', 1, 1 ),
               REGEXP_SUBSTR( value, '[^+]+', 1, 1 ),
               1
        FROM   your_source
        WHERE  name IS NOT NULL
        AND    value IS NOT NULL
      UNION ALL
        SELECT rid,
               name,
               value,
               REGEXP_SUBSTR( name, '[^+]+', 1, lvl + 1 ),
               REGEXP_SUBSTR( value, '[^+]+', 1, lvl + 1 ),
               lvl + 1
        FROM   splitstrings
        WHERE  lvl < LEAST(
                       REGEXP_COUNT( name, '[^+]+' ),
                       REGEXP_COUNT( value, '[^+]+' )
                     )
      )
      SELECT /* name, value, */ A,B,C,D
      FROM   ( SELECT rid, /* name, value, */ col, val FROM splitstrings )
      PIVOT  ( MAX( val ) FOR col IN ( 'A' AS a, 'B' AS b, 'C' AS c, 'D' AS d ) );
    

    Output:

    SELECT * FROM your_destination
    
    A  B  C  D
    -- -- -- --
    x2 x1 x3 x5
    y7    y4 y3
    
    0 讨论(0)
提交回复
热议问题