Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PIVOT in sql 2005

I need to pivot one column (Numbers column). example need this data:

a 1
a 2
b 3
b 4
c 5
d 6
d 7
d 8
d 9
e 10
e 11
e 12
e 13
e 14

Look like this

a 1 2
b 3 4
c 5
d 6 7 8 9
e 10 11 12 13 14

any help would be greatly appreciated...

like image 245
IZar Avatar asked Oct 13 '08 19:10

IZar


People also ask

How do you PIVOT in SQL query?

Introduction to SQL Server PIVOT operator You follow these steps to make a query a pivot table: First, select a base dataset for pivoting. Second, create a temporary result by using a derived table or common table expression (CTE) Third, apply the PIVOT operator.

Is there a PIVOT function in SQL?

You can use the PIVOT and UNPIVOT relational operators to change a table-valued expression into another table. PIVOT rotates a table-valued expression by turning the unique values from one column in the expression into multiple columns in the output.

When was SQL Server PIVOT added?

Microsoft introduced the PIVOT operator was introduced in SQL Server 2005, and it is this approach that we're going to discuss.

What is pivot table SQL Server 2008?

The PIVOT operator allows you to rotate data between columns and rows, performing aggregations along the way. UNPIVOT is the inverse of PIVOT, rotating data from columns to rows.


2 Answers

Using ROW_NUMBER(), PIVOT and some dynamic SQL (but no cursor necessary) :

CREATE TABLE [dbo].[stackoverflow_198716](
    [code] [varchar](1) NOT NULL,
    [number] [int] NOT NULL
) ON [PRIMARY]

DECLARE @sql AS varchar(max)
DECLARE @pivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @select_list AS varchar(max) -- Leave NULL for COALESCE technique

SELECT @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + CONVERT(varchar, PIVOT_CODE) + ']'
        ,@select_list = COALESCE(@select_list + ', ', '') + '[' + CONVERT(varchar, PIVOT_CODE) + '] AS [col_' + CONVERT(varchar, PIVOT_CODE) + ']'
FROM (
    SELECT DISTINCT PIVOT_CODE
    FROM (
        SELECT code, number, ROW_NUMBER() OVER (PARTITION BY code ORDER BY number) AS PIVOT_CODE
        FROM stackoverflow_198716
    ) AS rows
) AS PIVOT_CODES

SET @sql = '
;WITH p AS (
    SELECT code, number, ROW_NUMBER() OVER (PARTITION BY code ORDER BY number) AS PIVOT_CODE
    FROM stackoverflow_198716
)
SELECT code, ' + @select_list + '
FROM p
PIVOT (
    MIN(number)
    FOR PIVOT_CODE IN (
        ' + @pivot_list + '
    )
) AS pvt
'

PRINT @sql

EXEC (@sql)
like image 135
Cade Roux Avatar answered Sep 20 '22 21:09

Cade Roux


Just because I wanted to get some more experience with CTEs, I came up with the following:

WITH CTE(CTEstring, CTEids, CTElast_id)
AS
(
    SELECT string, CAST(id AS VARCHAR(1000)), id
    FROM dbo.Test_Pivot TP1
    WHERE NOT EXISTS (SELECT * FROM dbo.Test_Pivot TP2 WHERE TP2.string = TP1.string AND TP2.id < TP1.id)
    UNION ALL
    SELECT CTEstring, CAST(CTEids + ' ' + CAST(TP.id AS VARCHAR) AS VARCHAR(1000)), TP.id
    FROM dbo.Test_Pivot TP
    INNER JOIN CTE ON
        CTE.CTEstring = TP.string
    WHERE
        TP.id > CTE.CTElast_id AND
        NOT EXISTS (SELECT * FROM dbo.Test_Pivot WHERE string = CTE.CTEstring AND id > CTE.CTElast_id AND id < TP.id)
)
SELECT
    t1.CTEstring, t1.CTEids
FROM CTE t1
INNER JOIN (SELECT CTEstring, MAX(LEN(CTEids)) AS max_len_ids FROM CTE GROUP BY CTEstring) SQ ON SQ.CTEstring = t1.CTEstring AND SQ.max_len_ids = LEN(t1.CTEids)
ORDER BY CTEstring
GO

It might need some tweaking, but it worked with your example

like image 23
Tom H Avatar answered Sep 23 '22 21:09

Tom H