1

I have a table on which simple select gives out put like below

enter image description here

I want to write a select statement to output like below

enter image description here

Can someone help me...

4
  • 3
    Sounds like you want to pivot. Commented Dec 17, 2013 at 19:01
  • 1
    Search for pivot and sql. Commented Dec 17, 2013 at 19:02
  • How are you planning on displaying the data? Pivoting like this is typically much easier to do in reports and apps than in SQL. Commented Dec 17, 2013 at 19:03
  • Possible dupe: stackoverflow.com/questions/15091330/… Commented Dec 17, 2013 at 19:04

2 Answers 2

8

Since you are basically rotating your current columns of Sale, Income and Profit into rows and then move the month values to columns, then you will want to first unpivot the current columns, then pivot the months.

Depending on your version of SQL Server there are a few ways that you can unpivot the data. You can use the UNPIVOT function or CROSS APPLY:

select month, type, value
from yourtable
cross apply
(
  select 'Sale', sale union all
  select 'Income', Income union all
  select 'Profit', Profit
) c (type, value)

See SQL Fiddle with Demo. This will convert your current data into:

| MONTH |   TYPE | VALUE |
|-------|--------|-------|
|   Jan |   Sale |   100 |
|   Jan | Income |    50 |
|   Jan | Profit |    10 |
|   Feb |   Sale |    20 |
|   Feb | Income |    40 |

Then you can use the PIVOT function to convert the months into your column headers.

select type, Jan, Feb, Mar, Apr
from
(
  select month, type, value
  from yourtable
  cross apply
  (
    select 'Sale', sale union all
    select 'Income', Income union all
    select 'Profit', Profit
  ) c (type, value)
) d
pivot
(
  sum(value)
  for month in (Jan, Feb, Mar, Apr)
) piv;

See SQL Fiddle with Demo.

if you have an unknown number of months, then you can use dynamic SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct N',' + QUOTENAME(Month) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = N'SELECT type, ' + @cols + N' 
            from 
            (
                select month, type, value
                from yourtable
                cross apply
                (
                  select ''Sale'', sale union all
                  select ''Income'', Income union all
                  select ''Profit'', Profit
                ) c (type, value)
            ) x
            pivot 
            (
                sum(value)
                for month in (' + @cols + N')
            ) p '

execute sp_executesql @query;

See SQL Fiddle with Demo

Sign up to request clarification or add additional context in comments.

4 Comments

Solution looks good. Thank you bluefeet. But list of months is not known while writing the query, its dynamic. It may go up to December also. So today when I am running its till April, tomorrow it might be upto June. Any idea how to solve?
@KrishnarajBarvathaya See my edit, you will have to use dynamic sql. Is your month value actually a string - jan, feb, etc? Or it is stored as a date? You will have to do some adjustments to the code if it is stored as either but the above should get you started.
Is there any other direct way to convert rows to column and vise versa? Because whatever "yourtable" is not a simple table. Its a complex query with lot of conditions. Also I don't have the luxury to define separate variable and multiple statements. I should be able to convert columns to rows in a single statement.
@KrishnarajBarvathaya If you are going to have an unknown number of columns, then you have to use dynamic sql. It creates a sql string with all of the column name that will be executed, there is no easy way to do this dynamically.
0

You Can Use UNPIVOT then PIVOT
THE BEST IS TO DO QUERY EMBEDED SQL create DISTINCT COLUMS of months with STUFF function then replace FOR oMonth IN ([January-2013], [February-2013], [March-2013], [April-2013])
here core query

 SELECT  
*
FROM
(  SELECT      
 oMonth, value,col
 from (
 select DATENAME(month,oDate)   + '-' + CAST(YEAR(  oDate) as varchar) as oMonth,        Sales ,Income,Profit
 FROM            SalesSource 
 )A
unpivot
 (
  value for col in ( Sales ,Income,Profit)
 ) u

 ) as sourceTable
 PIVOT
 (
 sum( value)  
 FOR oMonth IN ([January-2013], [February-2013], [March-2013], [April-2013])
 ) AS PivotTable;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.