简体   繁体   中英

Table columns data to multiple rows

I met with some weird DB design during a data migration, and trying to convert a table data to a more normalized form. Here employees belongs to various positions and Employee-Position table looks like: EmpNo, Position1, SalCode1, Position2, SalCode2, Position3, SalCode3, Position4, SalCode4 etc.

EmpNo   Position01  SalCodeS01  Position02  SalCodeS02  Position03  SalCodeS03
E123    EL028       ENADV        EL029        ENADV     BF046       ENADV 
E125    EL028       LHENAD       EL029        LHENAD    BF046       LHENAD
E126    EL049       LHENAD       BF046        LHENAD    BF047       LHENAD
E127    EL028       LHENAD       EL029        LHENAD    BF046       LHENAD
E128    EL028       LHENAD       EL029        LHENAD    BF046       LHENAD
E129    EL049       LHENAD       BF046        LHENAD    BF047       LHENAD

Trying to normalize like EmpNo, Position, SalCode

EmpNo   Position    SalCode
E123    EL028      ENADV      
E123    EL029      ENADV      
E123    BF046      ENADV      
E123    BF047      ENADV      
E125    EL028      LHENAD     
E125    EL029      LHENAD     
E125    BF046      LHENAD     
E125    BF047      LHENAD     

Is anyone can suggest the best method to accomplish this? Is PIVOT possible? Thanks. PS. Please note that I have SELECT permission only and this is one table among 4 tables in a JOIN

may be something like this:

select EmpNo, Position01 as Position, SalCodeS01 as SalCode from  employees_table
union
select EmpNo, Position02 as Position, SalCodeS02 as SalCode from  employees_table
union
select EmpNo, Position03 as Position, SalCodeS03 as SalCode from  employees_table
order by EmpNo, Position

I suggest you write a procedure to do this task. Define a cursor and for each iteration of the cursor, do this.

INSERT INTO employee_positions_new (EmpNo, Position01, SalCodeS01);
INSERT INTO employee_positions_new (EmpNo, Position02, SalCodeS02);
INSERT INTO employee_positions_new (EmpNo, Position03, SalCodeS03);
CREATE TABLE #temp
  (
     EmpNo      VARCHAR(50),
     Position01 VARCHAR(50),
     SalCodeS01 VARCHAR(50),
     Position02 VARCHAR(50),
     SalCodeS02 VARCHAR(50),
     Position03 VARCHAR(50),
     SalCodeS03 VARCHAR(50)
  )

INSERT INTO #temp
            (EmpNo,Position01,SalCodeS01,Position02,
             SalCodeS02,Position03,SalCodeS03)
VALUES      ('E123','EL028','ENADV','EL029',
             'ENADV','BF046','ENADV'),
            ('E125','EL028','LHENAD','EL029',
             'LHENAD','BF046','LHENAD'),
            ('E126','EL049','LHENAD','BF046',
             'LHENAD','BF047','LHENAD')

SELECT A.EmpNo,
       a.Position,
       b.SalCode
FROM   (SELECT empno,
               Split.a.value('.', 'VARCHAR(100)') Position
        FROM   (SELECT empno,
                       Cast ('<M>'
                             + Replace(Position01+','+Position02+','+Position03, ',', '</M><M>')
                             + '</M>' AS XML) AS Data
                FROM   #temp) AS A
               CROSS APPLY Data.nodes ('/M') AS Split(a)) A
       JOIN (SELECT empno,
                    Split.a.value('.', 'VARCHAR(100)') SalCode
             FROM   (SELECT empno,
                            Cast ('<M>'
                                  + Replace(SalCodeS01+','+SalCodeS02+','+SalCodeS03, ',', '</M><M>')
                                  + '</M>' AS XML) AS Data
                     FROM   #temp) AS A
                    CROSS APPLY Data.nodes ('/M') AS Split(a)) B
         ON a.EmpNo = b.EmpNo 

OUTPUT

   EmpNo    Position    SalCode
    E123    EL028   ENADV
    E123    EL029   ENADV
    E123    BF046   ENADV
    E123    EL028   ENADV
    E123    EL029   ENADV
    E123    BF046   ENADV
    E123    EL028   ENADV
    E123    EL029   ENADV
    E123    BF046   ENADV
    E125    EL028   LHENAD
    E125    EL029   LHENAD
    E125    BF046   LHENAD
    E125    EL028   LHENAD
    E125    EL029   LHENAD
    E125    BF046   LHENAD
    E125    EL028   LHENAD
    E125    EL029   LHENAD
    E125    BF046   LHENAD
    E126    EL049   LHENAD
    E126    BF046   LHENAD
    E126    BF047   LHENAD
    E126    EL049   LHENAD
    E126    BF046   LHENAD
    .......

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM