2008-11-23 13 views
15

Ich habe ein Beispielszenario meines Problems zusammengestellt und ich hoffe, es ist genug für jemanden, der mir in die richtige Richtung zeigen.Pivot mit SQL Server 2000

Ich habe zwei Tabellen

Produkte

alt text

Produkt Meta

alt text

ich eine Ergebnismenge der folgenden

benötigen

die gespeicherte Prozedur

Antwort

14

Wir haben erfolgreich den folgenden Ansatz in der Vergangenheit ...

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 

Es ist auch nützlich zur Umsetzung der Aggregationen mit dem Einsatz von ...

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

sein kann EDIT

Auch erwähnenswert ist dies mit ANSI-Standard SQL und so funktioniert es plattformübergreifend :)

+0

Das funktioniert nur Wenn die Werte statisch sind - dh, Sie wissen im Voraus die Spaltenwerte .. –

+0

eine Sache, die ich es nicht verstehe, ist, wenn Sie [m] .metavalue in allen Schalterfällen dann verwenden müssen, warum Schalterfall verwenden, können Sie erklären ein bisschen. – Alex

+0

Weil zum Beispiel nur die Summe von [m] .metavalue gewünscht wird, wobei [m] .metakey in Spalte a "a" ist. Im Wesentlichen filtert es alle anderen metavalue Ergebnisse der Summe aus. Auf diese Weise können Sie die Daten in den ursprünglichen Zeilen in Spalten transponieren. –

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

Danke GregD aber ich fürchte, das wird mir nicht helfen. Das Problem ist, dass, wenn ein neuer Datensatz zur ProductMeta-Tabelle hinzugefügt wird, ich zurückgehen und diese Aussage ändern muss. Ich versuche meine Wartungspunkte so niedrig wie möglich zu halten. – sykespro

+0

Ah..Ok Dann werden Sie wahrscheinlich einen Blick auf diesen Artikel werfen wollen: http://www.oreillynet.com/pub/a/network/2004/12/17/crosstab.html – GregD

6

Wenn Ihre Datenbank-Engine 2005 ist und Ihre Datenbank im Kompatibilitätsmodus 2000 ist, können Sie den niedrigeren Kompatibilitätsmodus umgehen, indem Sie Ihre Abfrage aus einer 2005-Datenbank ausführen. Richten Sie die 2000-Datenbank aus, indem Sie die 3-teilige Benennungskonvention für Ihre Tabellen in der Abfrage wie DatabaseNameHere.dbo.TableNameHere

24

verwenden. Ich weiß, dass dies zwei Jahre alt ist, aber es stört mich, dass die akzeptierte Antwort die Verwendung von dynamischem SQL und der meistbeworbenen Antwort erfordert ‚t Arbeit:

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 

Sie müssen eine Gruppe von verwenden, oder Sie werden ein gestaffeltes Ergebnis. Wenn Sie eine Gruppierung nach verwenden, müssen Sie jede Spalte, die sich nicht in der Gruppierung nach befindet, in eine Aggregatfunktion (oder eine Unterabfrage) umbrechen.

+1

Ich habe gerade eine schrecklich langsame Pivot-Abfrage überarbeitet, um die Methode hier mit min() zu verwenden und die Abfrage in weniger als 2 Sekunden ausgeführt. Ich vergebe dir +2 Internets! – Kirk