Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 Help with output of pivot query

Author  Topic 

millaine
Starting Member

6 Posts

Posted - 2009-06-22 : 10:40:58
Hi all,

I've written a pivot query and the results I get are something like this -

Column1 Column2 Column3 Column4 Column5
10 NULL NULL NULL NULL
NULL 20 NULL NULL NULL
NULL NULL 30 NULL NULL
NULL NULL NULL 40 NULL

Is it possible to modify the query so that it returns just one row with 10 under column1, 20 under column2, 30 under column3 and 40 under column4?

I'd really appreciate help on this...

Thanks in anticipation.

Millaine.

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2009-06-22 : 10:48:08
Post your query.

I'm guessing that all you need to do is group by the primary key and use syntax such as this for col1,2,3,4

DECLARE @Foo TABLE (
[ID] INT
, [key] NVARCHAR(5)
, [value] INT
)

INSERT @foo ([Id], [key], [value])
SELECT 1, 'A', 10
UNION SELECT 1, 'B', 20
UNION SELECT 1, 'C', 50
UNION SELECT 2, 'A', 10
UNION SELECT 4, 'D', 100

SELECT * FROM @foo

-- With implicit 0 if no data (note this will be *WRONG* if you have negative integers in results)
SELECT
f.[Id]
, MAX(CASE WHEN f.[key] = 'A' THEN f.[value] ELSE 0 END) AS [A]
, MAX(CASE WHEN f.[key] = 'B' THEN f.[value] ELSE 0 END) AS [B]
, MAX(CASE WHEN f.[key] = 'C' THEN f.[value] ELSE 0 END) AS [C]
, MAX(CASE WHEN f.[key] = 'D' THEN f.[value] ELSE 0 END) AS [D]
FROM
@foo f
GROUP BY
f.[ID]

-- Treat no data as NULL
SELECT
f.[Id]
, MAX(CASE WHEN f.[key] = 'A' THEN f.[value] END) AS [A]
, MAX(CASE WHEN f.[key] = 'B' THEN f.[value] END) AS [B]
, MAX(CASE WHEN f.[key] = 'C' THEN f.[value] END) AS [C]
, MAX(CASE WHEN f.[key] = 'D' THEN f.[value] END) AS [D]
FROM
@foo f
GROUP BY
f.[ID]



Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-06-22 : 10:49:11
yup. GROUP By the common field and apply MIN() or MAX() over measure field.
Go to Top of Page

vijayisonly
Master Smack Fu Yak Hacker

1836 Posts

Posted - 2009-06-22 : 10:49:17
quote:
Originally posted by millaine

Hi all,

I've written a pivot query and the results I get are something like this -

Column1 Column2 Column3 Column4 Column5
10 NULL NULL NULL NULL
NULL 20 NULL NULL NULL
NULL NULL 30 NULL NULL
NULL NULL NULL 40 NULL

Is it possible to modify the query so that it returns just one row with 10 under column1, 20 under column2, 30 under column3 and 40 under column4?

I'd really appreciate help on this...

Thanks in anticipation.

Millaine.



You have to group by your remaining columns which are repeating.
Go to Top of Page

millaine
Starting Member

6 Posts

Posted - 2009-06-22 : 11:19:57
Wow guys! Tremendously fast response...

This is the query.

DECLARE @columns VARCHAR(8000)

SELECT @columns = COALESCE(@columns + ',[' + cast(payitemname as varchar) + ']',
'[' + cast(payitemname as varchar)+ ']')
FROM tbl_Payroll_Items_Generation
GROUP BY payitemname

DECLARE @query VARCHAR(8000)

SET @query = '
SELECT *
FROM tbl_Payroll_Items_Generation
PIVOT
(
MAX(amount)
FOR payitemname
IN (' + @columns + ')
)
AS p where payrollid=5'

EXECUTE(@query)

So as you can see, I dont know the number of columns or column names till I actually run this query. So am not sure how the use of case statements can help.

My original table is in this format

ID name amount
1 value1 10
2 value2 20
3 value3 30
4 value4 40

I now need to write a query to get something like

Value1 value2 value3 value4
10 20 30 40

but i get

value1 value2 value3 value4
10 NULL NULL NULL
NULL 20 NULL NULL
NULL NULL 30 NULL
NULL NULL NULL 40

& i need to get rid of the nulls with one row only.

I can do the group by if i know beforehand details of my columns but since they are gotten from a pivot query, am not sure how to go about that.

Please bear with me, am a .net programmer, i usually do clr in sql server 2005, but this is one time i JUST GOTTA do it the "back end" way... *grins*

Thanks in anticipation!
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-06-22 : 11:25:39
how do you decide that above four values should be on same row? do you have another column which has same value for all the four rows i.e relates all of above four rows? or does your table contain only four rows always?
Go to Top of Page

millaine
Starting Member

6 Posts

Posted - 2009-06-22 : 11:32:24
Yeah, i Have a staff id column that has the same values for all rows.
The table contains thousands of rows. But about 10 rows per staff ID with those NULL values coming in between.

I think I maybe need a way to do a dynamic groupby
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2009-06-22 : 11:43:20
Here's one way that will generate dynamic column names based on the distinct [name] entries in the table
:

IF OBJECT_ID('tempdb..#foo') IS NOT NULL DROP TABLE #foo
DECLARE @sql NVARCHAR(MAX)

CREATE TABLE #Foo (
[ID] INT
, [staffId] INT
, [name] NVARCHAR(50)
, [amount] INT
)

INSERT #foo ([Id], [staffId], [name], [amount])
SELECT 1, 1, 'value1', 10
UNION SELECT 2, 1, 'value2', 20
UNION SELECT 3, 1, 'value3', 50
UNION SELECT 4, 1, 'value4', 10
UNION SELECT 5, 2, 'value1', 100
UNION SELECT 6, 2, 'value3', 10
UNION SELECT 7, 2, 'FOOO', 45
UNION SELECT 7, 2, 'BAR', 123

SELECT * FROM #foo

-- Dyanmic Pivot with column Names
SET @sql = N'
SELECT
[staffID]'

SELECT @sql = @sql + N'
, MAX(CASE WHEN [name] = ''' + [name] + ''' THEN [amount] ELSE NULL END) AS [' + [name] + ']'
FROM
( SELECT DISTINCT [name] FROM #foo ) f

SET @sql = @sql + N'
FROM
#foo
GROUP BY
[staffId]'

EXEC sp_executeSql @sql


It's actually generally a lot better to do this in your external application. Do a search for DYNAMIC CROSS TAB in this forum for some other approaches.

Good Luck.

Edit
The results:

staffID BAR FOOO value1 value2 value3 value4
----------- ----------- ----------- ----------- ----------- ----------- -----------
1 NULL NULL 10 20 50 10
2 123 45 100 NULL 10 NULL


Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-06-22 : 11:45:45
http://sqlblogcasts.com/blogs/madhivanan/archive/2007/08/27/dynamic-crosstab-with-multiple-pivot-columns.aspx

Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2009-06-22 : 11:52:11
Cheers Viskah, that's the one I was thinking of.


Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-06-22 : 12:06:45
Cheers
Go to Top of Page

millaine
Starting Member

6 Posts

Posted - 2009-06-22 : 12:33:53
thanks visakh, charlie, everyone.

I owe y'all a drink, in this life and the next...

The link from sqlblogcasts was splendid...!!!
Go to Top of Page
   

- Advertisement -