2008-11-23 20 views
15

Armado un escenario de ejemplo de mi problema y espero que sea suficiente para que alguien me señale en la dirección correcta.Pivot usando SQL Server 2000

que tienen dos mesas

productos

alt text

Meta Producto

alt text

necesito un conjunto de resultados de la siguiente

alt text

Respuesta

14

Hemos utilizado con éxito el siguiente enfoque en el pasado ...

SELECT [p].ProductID, 
     [p].Name, 
     MAX(CASE [m].MetaKey 
      WHEN 'A' 
       THEN [m].MetaValue 
      END) AS A, 
     MAX(CASE [m].MetaKey 
      WHEN 'B' 
       THEN [m].MetaValue 
      END) AS B, 
     MAX(CASE [m].MetaKey 
      WHEN 'C' 
       THEN [m].MetaValue 
      END) AS C 
FROM Products [p] 
     INNER JOIN ProductMeta [m] 
     ON [p].ProductId = [m].ProductId 
GROUP BY [p].ProductID, 
      [p].Name 

También puede ser agregaciones de transposición útiles con el uso de ...

SUM(CASE x WHEN 'y' THEN yVal ELSE 0 END) AS SUMYVal 

EDIT

También vale la pena señalar que esto es mediante el estándar ANSI SQL y así funcionará en plataformas :)

+0

Esto solo funciona cuando los valores son estáticos, es decir, usted conoce con anticipación los valores de la columna ... –

+0

una cosa que no entiendo es si necesita usar [m] .metavalue en todos los casos, entonces ¿por qué molestarse con el uso de la caja del interruptor? ¿Puede explicarlo? un poco. – Alex

+0

Porque, por ejemplo, solo desea la suma de [m] .metavalue donde [m] .metakey es 'a' para aparecer en la columna a. Básicamente, filtra todos los demás resultados de metavalor de la suma. De esta forma, puede transponer los datos en las filas originales en columnas. –

3
Select a.ProductId 
    ,a.Name 
    ,(Select c.MetaValue 
    From [Product Meta] c 
    Where c.ProductId = a.ProductId 
    And c.MetaKey = 'A') As 'A' 
    ,(Select d.MetaValue 
    From [Product Meta] d 
    Where d.ProductId = a.ProductId 
    And d.MetaKey = 'B') As 'B' 
    ,(Select e.MetaValue 
     From [Product Meta] e 
     Where e.ProductId = a.ProductId 
     And e.MetaKey = 'C') As 'C' 
From Products a 
Order By a.ProductId Asc 
+2

Gracias GregD, pero me temo que esto no me ayudará. El problema es que cuando se agrega un nuevo registro a la tabla ProductMeta tendré que volver atrás y modificar esta declaración. Estoy tratando de mantener mis puntos de mantenimiento lo más bajo posible. – sykespro

+0

Ah..Ok Entonces es probable que desee echar un vistazo a este artículo: http://www.oreillynet.com/pub/a/network/2004/12/17/crosstab.html – GregD

6

Si su motor de base de datos es 2005 y su base de datos está en modo de compatibilidad 2000, puede trabajar en el modo de compatibilidad inferior ejecutando su consulta desde una base de datos 2005. Apunte a la base de datos 2000 utilizando la convención de nomenclatura de 3 partes para sus tablas en la consulta como DatabaseNameHere.dbo.TableNameHere

24

Me doy cuenta de que esto tiene dos años, pero me molesta que la respuesta aceptada requiera el uso de SQL dinámico y la respuesta más votada ganada 't trabajo:

Select P.ProductId, P.Name 
    , Min(Case When PM.MetaKey = 'A' Then PM.MetaValue End) As A 
    , Min(Case When PM.MetaKey = 'B' Then PM.MetaValue End) As B 
    , Min(Case When PM.MetaKey = 'C' Then PM.MetaValue End) As C 
From Products As P 
     Join ProductMeta As PM 
      On PM.ProductId = P.ProductId 
Group By P.ProductId, P.Name 

usted debe Por utilizar un Grupo o se obtendrá un resultado escalonada. Si está utilizando un Agrupar por, debe ajustar cada columna que no está en la cláusula Agrupar por en una función agregada (o una subconsulta).

+1

Acabo de volver a trabajar una consulta de pivote terriblemente lenta para usar el método aquí con min() y mejoré la consulta para ejecutar en menos de 2 segundos. ¡Te otorgo +2 internets! – Kirk

Cuestiones relacionadas