Question

I have a table( in SQL Server 2008) which has vertical sales transactions data, i would like to convert vertical output to horizontal output, i tried to use PIVOT, but some how not getting idea how to apply group by on PIVOT, as i want Sum based on AccountHeadID, TransType and IsPast Column.

Sample Table

CREATE TABLE Trans
    ([TransID] int,
     [CustID] int,
     [AccountHeadID] int,
     [TransType] varchar(100),
     [IsPast] bit,
     [Amount] int)
;

INSERT INTO Trans
    ([TransID],CustID, [AccountHeadID], [TransType], [IsPast],[Amount])
VALUES
    (1, 1, 1, 'Sales',1,1000),
    (2, 1, 1, 'Sales',0,500),
    (3, 1, 1, 'Sales',0,400),
    (4, 1, 1, 'Return',0,300),
    (5, 1, 1, 'Return',0,200),
    (6, 1, 1, 'Return',0,100),
    (7, 1, 1, 'Return',1,150),
    (8, 1, 2, 'Sales',1,2000)   

Current Query

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

select @cols = STUFF((SELECT ',' + QUOTENAME(AccountHeadID)  
                    from Trans
                    group by AccountHeadID
                    order by AccountHeadID
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT CustID,' + @cols + ' 
            from 
            (
              SELECT 
                a.CustID,
                a.AccountHeadID,
                 a.TransType,
                 a.Amount,
                 a.isPast
              FROM Trans a
            ) x
            pivot 
            (
                sum(Amount)
                for AccountHeadID in (' + @cols + ')
            ) p '

execute sp_executesql @query;

Expected Output

CustID | Account-HeadID-TransType-IsPast[1-Sales-Past] |  Account-HeadID-TransType-IsCurrent[1-Sales-Current] | Account-HeadID-TransType-IsCurrent[1-Return-Past] |  Account-HeadID-TransType-IsCurrent[1-Return-Current] | Account-HeadID-TransType-IsCurrent[2-Sales-Past]| ...
1      |1000                                           | 900 (500 + 400)                                      |150                                                | 600[300+200+100]                                       |2000   

See SQL Fiddle with Demo

Any suggestion or input are most welcome!

Thanks Suresh

Was it helpful?

Solution

Try this:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(CONVERT(NVARCHAR(10),AccountHeadID) + N'-' + TransType + N'-' + CONVERT(NVARCHAR(10),IsPast))  
                    from Trans
                    group by AccountHeadID, TransType, IsPast
                    order by AccountHeadID, TransType, IsPast
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

--select @cols

set @query = 'SELECT CustID,' + @cols + ' 
            from 
            (
              SELECT 
                a.CustID,
                CONVERT(NVARCHAR(10),AccountHeadID) + N''-'' + TransType + N''-'' + CONVERT(NVARCHAR(10),IsPast) Acct,
                 a.Amount
              FROM Trans a
            ) x
            pivot 
            (
                sum(Amount)
                for Acct in (' + @cols + ')
            ) p '

execute sp_executesql @query;

SQL Fiddle

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top