2011-08-24 11 views
6

SELECT Name1, Name2, Value FROM mytable me da el siguiente conjunto de resultados:SQL Server PIVOT quizás?

 
Name1 Name2 Value 
A  P1  1 
A  P2  1 
A  P3  2 
B  P1  3 
B  P2  1 
B  P4  1 

¿Cómo traduzco a que:

 
     A  B 
P1  1  4 
P2  1  1 
P3  2  null 
P4  null 1 

Gracias,

+1

Hola! @user ¿Qué DBMS estás usando? – jadarnel27

+0

¿Son A y B una lista fija de constantes? – Neil

+0

@ jadarnel27 - Hay una pista en el título de la pregunta;) – Tony

Respuesta

1

Puede utilizar una cláusula PIVOT. Su consulta podría ser algo como esto:

WITH Source as (
    SELECT Name1, Name2, [Value] 
    FROM mytable 
) 

SELECT Name2, CASE WHEN A IS NOT NULL THEN A ELSE 'your string' END As A 
, CASE WHEN B IS NOT NULL THEN B ELSE 'your string' END As B 
FROM (
     SELECT Name2, Name1, [Value] 
     FROM Source 
) s 
PIVOT 
(
    MAX([Value]) FOR Name1 IN (A, B) -- any other Name1 would go here 
) p 

el uso de sus datos de ejemplo anterior, mis resultados fueron

P1 1   3 
P2 1   1 
P3 2   your string 
P4 your string 1 

EDIT:

Puesto que usted tiene un número desconocido de columnas, que necesitará mire utilizando SQL dinámico y hay varias respuestas aquí en SO sobre eso con PIVOT.

SQL Server 2005 Pivot on Unknown Number of Columns

Pivot Table and Concatenate Columns

+0

El problema es que el OP no puede limitar el resultado a A, B. También puede haber C, ..., X, como dijo en uno de los comentarios. –

+0

Hice algunas modificaciones y pude hacer que funcionara al usar este ejemplo y http://stackoverflow.com/questions/159456/pivot-table-and-concatenate-columns-sql-problem#159803. Una última cosa, ¿cómo voy a reemplazar los NULL con otra cadena? Intenté una CASE pero solo reemplaza los campos 'Valor' que tienen valores, no los NULL – user683302

+0

Actualicé la consulta PIVOT anterior utilizando CASE y los valores de NUll se cambian a una cadena. – Taryn

4

no tengo ejecución de SQL Server aquí en el trabajo así que esto no puede por completo syntatically correcta, pero un enfoque sería tabulación cruzada

SELECT name2 
    , SUM(CASE WHEN name1 = 'A' THEN value END) AS A 
    , SUM(CASE WHEN name1 = 'B' THEN value END) AS B 
FROM table 
GROUP BY name2 

Por número variable de columnas puede usar SQL dinámico:

DECLARE @sql varchar(max) 
SELECT @sql = COALESCE(@sql+',','') + 'SUM(CASE WHEN nane1 = '''+name1+''' THEN value END) AS ['+name1']' FROM table 

SET @sql = 'SELECT name2, '[email protected]+' FROM table GROUP BY name2' 

EXEC(@sql) 
+3

Tisk, tisk ... respondiendo ASÍ preguntas en el trabajo =) – jadarnel27

+0

Estaba esperando a que compile mi código :-P – Zugwalt

+2

Hay mucho [más constructivo] (http: // xkcd.com/303/) cosas que puede hacer mientras se compila su código;) Publiqué ese comentario mientras estaba en el trabajo, así haha ​​ – jadarnel27

11

Puesto que usted está utilizando SQL Server 2005, aquí está el código:

DECLARE @cols VARCHAR(1000) 
DECLARE @sqlquery VARCHAR(2000) 

SELECT @cols = STUFF((SELECT distinct ',' + QuoteName([Name1]) 
         FROM myTable FOR XML PATH('')), 1, 1, '') 


SET @sqlquery = 'SELECT * FROM 
     (SELECT Name2, Name1, Value 
     FROM myTable) base 
     PIVOT (Sum(Value) FOR [Name1] 
     IN (' + @cols + ')) AS finalpivot' 

EXECUTE (@sqlquery) 

Esto funcionará sin importar cuántas estatus diferente que tiene. Arregla dinámicamente una consulta con PIVOT. La única forma en que puede hacer PIVOT con columnas dinámicas es ensamblando la consulta dinámicamente, lo que se puede hacer en SQL Server.

Otros ejemplos:

+2

+1 para 'Nombre de punto ' –

+0

@Martin ¡Evita los ataques de inyección! –

+1

+1 Estoy sin palabras. –