Pivot using SQL Server 2000

26,519

Solution 1

We've successfully used the following approach in the past...

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 

It can also be useful transposing aggregations with the use of...

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

EDIT

Also worth noting this is using ANSI standard SQL and so it will work across platforms :)

Solution 2

I realize this is two years old, but it bugs me that the accepted answer calls for using dynamic SQL and the most upvoted answer won't work:

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

You must use a Group By or you will get a staggered result. If you are using a Group By, you must wrap each column that is not in the Group By clause in an aggregate function (or a subquery).

Solution 3

If your database engine is 2005 and your database is in 2000 compatibility mode, you can work around the lower compatibility mode by running your query from a 2005 database. Target the 2000 database by using 3 part naming convention for your tables in the query such as DatabaseNameHere.dbo.TableNameHere

Solution 4

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
Share:
26,519
sykespro
Author by

sykespro

Hello everyone my name is Daniel Sykes. I was born February 18, 1981 in Brooklyn NY. I currently reside in Brandon FL. I’ve been enjoying the sunshine state for about 5 years. While taking advantage of the nice weather I was working towards my bachelors in web development which I completed June 06. I have been programming client and server code for the last 5 years. Web development was the next step up from my associates I received when I was back home (New York) in graphic design. I have been doing graphic design work for about 8 year in total but for the last 5 years I focused primary on web design.

Updated on July 21, 2020

Comments

  • sykespro
    sykespro almost 4 years

    I put together a sample scenario of my issue and I hope its enough for someone to point me in the right direction.

    I have two tables

    Products

    alt text

    Product Meta

    alt text

    I need a result set of the following

    alt text

  • sykespro
    sykespro over 15 years
    Thanks GregD but Im afraid this wont help me. The problem is that when there is a new record added to the ProductMeta table I will have to go back and alter this statement. Im trying to keep my maintenance points as low as possible.
  • GregD
    GregD over 15 years
    Ah..Ok Then you're probably going to want to take a look at this article: oreillynet.com/pub/a/network/2004/12/17/crosstab.html
  • M.R.
    M.R. about 13 years
    This only works when the values are static - i.e., you know ahead of time the column values..
  • Kirk
    Kirk about 12 years
    I just reworked a terribly slow pivot query to use the method here with min() and improved the query to execute in under 2 seconds. I award you +2 internets!
  • user786
    user786 about 8 years
    one thing i dont get it is if you need to use [m].metavalue in all switch cases then why bother using switch case, can u explain a little bit.
  • Rich Andrews
    Rich Andrews about 8 years
    Because, for example, you only want the sum of [m].metavalue where [m].metakey is 'a' to appear in column a. Essentially it filters out out all other metavalue results of the sum. In this way you can transpose the data in the original rows into columns.