表将数据列到多行

时间:2014-08-27 07:00:40

标签: sql sql-server sql-server-2008 tsql sql-server-2005

我在数据迁移期间遇到了一些奇怪的数据库设计,并尝试将表数据转换为更规范化的表单。 员工在这里属于各种职位,员工职位表如下:EmpNo, Position1, SalCode1, Position2, SalCode2, Position3, SalCode3, Position4, SalCode4等。

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

尝试像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     

有人能提出最好的方法吗? PIVOT可能吗?谢谢。 PS。请注意,我只有SELECT权限,这是JOIN中4个表中的一个表

3 个答案:

答案 0 :(得分:1)

可能是这样的:

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

答案 1 :(得分:0)

我建议你写一个程序来完成这个任务。定义游标,并为游标的每次迭代执行此操作。

INSERT INTO employee_positions_new (EmpNo, Position01, SalCodeS01);
INSERT INTO employee_positions_new (EmpNo, Position02, SalCodeS02);
INSERT INTO employee_positions_new (EmpNo, Position03, SalCodeS03);

答案 2 :(得分:0)

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 

输出

   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
    .......