Search code examples
sqlsql-serversql-server-2014

How to unpivot from a long to a wide table?


My data in testtable:

FechaRegistro IdRecordRedcap FechaRegistro diario_total_pruebas diario_pruebas_negativas diario_pruebas_rechazadas
15 15 2022-01-06 510 384 NULL

I require to unpivot the following data without the UNPIVOT function

FechaRegistro IdRecordRedcap Var Value
2022-01-06 15 diario_total_pruebas 510
2022-01-06 15 diario_pruebas_negativas 384
2022-01-06 15 diario_pruebas_rechazadas null

Structure and sample data in this db<>fiddle


Solution

  • -- on SQL Server 2000 you must have a death wish
    
      SELECT FechaRegistro, IdRecordRedcap,
             Var   = 'diario_total_pruebas',
             Value =  diario_total_pruebas 
      FROM dbo.testtable
    
      UNION ALL
    
      SELECT FechaRegistro, IdRecordRedcap,
             Var   = 'diario_pruebas_negativas',
             Value =  diario_pruebas_negativas 
      FROM dbo.testtable
    
      UNION ALL
    
      SELECT FechaRegistro, IdRecordRedcap,
             Var   = 'diario_pruebas_rechazadas',
             Value =  diario_pruebas_rechazadas 
      FROM dbo.testtable;
    

    To be fair, to have the UNPIVOT solution on versions published this century deal with NULLs correctly, it's not that much cleaner:

    -- on SQL Server 2005 and later
    
    ;WITH x AS 
    (
      SELECT FechaRegistro, IdRecordRedcap, 
        diario_total_pruebas      = COALESCE(diario_total_pruebas,      -1),
        diario_pruebas_negativas  = COALESCE(diario_pruebas_negativas,  -1),
        diario_pruebas_rechazadas = COALESCE(diario_pruebas_rechazadas, -1)
      FROM dbo.testtable
    )
    SELECT FechaRegistro, IdRecordRedcap, 
           Var, Value = NULLIF(Value, -1)
      FROM x UNPIVOT 
      (
         Value FOR Var IN
         (
           diario_total_pruebas,
           diario_pruebas_negativas,
           diario_pruebas_rechazadas
         )
      ) AS u;
    

    Output in both cases:

    FechaRegistro IdRecordRedcap Var Value
    2022-01-06 15 diario_total_pruebas 510
    2022-01-06 15 diario_pruebas_negativas 384
    2022-01-06 15 diario_pruebas_rechazadas null