如何从长轴转为宽轴 table?

How to unpivot from a long to a wide table?

我在testtable中的数据:

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

我需要在没有 UNPIVOT 函数的情况下逆透视以下数据

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

UNPIVOT 是在 SQL Server 2005 中引入的。如果你真的使用 SQL Server 2000,你会遇到比 UNPIVOTing 更大的问题。配备 SQL Server Express 的笔记本电脑比 20 年前可用的任何东西(多核还不是一回事)都更强大,具有更快的磁盘、更多的 RAM 和 CPU 内核。而且也更安全。

如果没有 UNPIVOT,您可能需要编写与要逆透视的列一样多的查询,并将它们与 UNION ALL 组合起来:

select FechaRegistro,IdRecordRedcap,'diario_total_pruebas' as Var,
diario_total_pruebas as Value
from testtable
UNION ALL
select FechaRegistro,IdRecordRedcap,'diario_pruebas_negativas' as Var,
diario_pruebas_negativas   as Value
from testtable
...
-- 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;

公平地说,要让本世纪发布的版本的 UNPIVOT 解决方案正确处理 NULLs,它并没有那么干净:

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

两种情况下的输出:

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