sql - transponer - Pivote las filas a columnas sin agregado
sql transponer columnas a filas (3)
Tratando de averiguar cómo escribir una declaración dinámica de sql de pivote. Donde TEST_NAME
podría tener hasta 12 valores diferentes (por lo tanto, tener 12 columnas). Algunos de los valores de VAL serán tipos de datos Int, Decimal o Varchar. La mayoría de los ejemplos que he visto tienen algunos de agregados incluidos. Estoy buscando un pivote de valor directo.
Source Table
╔═══════════╦══════╦═══════╗
║ TEST_NAME ║ SBNO ║ VAL ║
╠═══════════╬══════╬═══════╣
║ Test1 ║ 1 ║ 0.304 ║
║ Test1 ║ 2 ║ 0.31 ║
║ Test1 ║ 3 ║ 0.306 ║
║ Test2 ║ 1 ║ 2.3 ║
║ Test2 ║ 2 ║ 2.5 ║
║ Test2 ║ 3 ║ 2.4 ║
║ Test3 ║ 1 ║ PASS ║
║ Test3 ║ 2 ║ PASS ║
╚═══════════╩══════╩═══════╝
Desired Output
╔══════════════════════════╗
║ SBNO Test1 Test2 Test3 ║
╠══════════════════════════╣
║ 1 0.304 2.3 PASS ║
║ 2 0.31 2.5 PASS ║
║ 3 0.306 2.4 NULL ║
╚══════════════════════════╝
La función PIVOT
requiere una agregación para que funcione. Parece que su columna VAL
es una varchar
por lo que tendrá que usar las funciones de MAX
o MIN
.
Si el número de pruebas es limitado, puede codificar los valores:
select sbno, Test1, Test2, Test3
from
(
select test_name, sbno, val
from yourtable
) d
pivot
(
max(val)
for test_name in (Test1, Test2, Test3)
) piv;
Ver SQL Fiddle con Demo .
En su OP, usted declaró que tendrá un número mayor de filas para convertir en columnas. Si ese es el caso, entonces puedes usar SQL dinámico:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct '','' + QUOTENAME(TEST_NAME)
from yourtable
FOR XML PATH(''''), TYPE
).value(''.'', ''NVARCHAR(MAX)'')
,1,1,'''')
set @query = ''SELECT sbno,'' + @cols + ''
from
(
select test_name, sbno, val
from yourtable
) x
pivot
(
max(val)
for test_name in ('' + @cols + '')
) p ''
execute(@query)
Ver SQL Fiddle con Demo .
Ambas versiones darán el mismo resultado:
| SBNO | TEST1 | TEST2 | TEST3 |
---------------------------------
| 1 | 0.304 | 2.3 | PASS |
| 2 | 0.31 | 2.5 | PASS |
| 3 | 0.306 | 2.4 | (null) |
No hay ninguna manera de PIVOT sin agregar.
CREATE TABLE #table1
(
TEST_NAME VARCHAR(10),
SBNO VARCHAR(10),
VAL VARCHAR(10)
);
INSERT INTO #table1 (TEST_NAME, SBNO, VAL)
VALUES (''Test1'' ,''1'', ''0.304''),
(''Test1'' ,''2'', ''0.31''),
(''Test1'' ,''3'', ''0.306''),
(''Test2'' ,''1'', ''2.3''),
(''Test2'' ,''2'', ''2.5''),
(''Test2'' ,''3'', ''2.4''),
(''Test3'' ,''1'', ''PASS''),
(''Test3'' ,''2'', ''PASS'')
WITH T AS
(
SELECT SBNO, VAL, TEST_NAME
FROM #table1
)
SELECT *
FROM T
PIVOT (MAX(VAL) FOR TEST_NAME IN([Test1], [Test2], [Test3])) P
Una solución alternativa podría ser garantizar que la agregación obligatoria solo se aplique a un solo registro. En Excel, por ejemplo, la salida podría ser:
donde Etiquetas de fila incluye en la parte inferior una columna de celdas con números de índice únicos.