如何将行转换为列?

时间:2013-06-15 19:40:22

标签: sql vb.net winforms sql-server-ce pivot

我有下表:

  PROCESS ID       VOUCHER DATE     CATEGORY_ID     PROJECT     AMOUNT
  -----------      ------------    ------------     -------     -------
  1001             12/03/13         Miscellaneous   pnr         1000
  1001             12/03/13         Miscellaneous   pjk         2000
  1002             20/07/13         Local Travel    pnr         3000
  1002             20/07/13         Local Travel    npk         3400
  1003             29/09/14         Miscellaneous   jpg         1000
  1004             23/10/13         Local Travel    pnr         2000
  1005             24/10/13         Miscellaneous   pnr         1000
  1005             24/10/13         Local Travel    pnr         1000

在界面中,我会在某个日期之间提供 VOUCHER DATE ,例如 20/01/13 27/10/13 ,我必须得到以下格式的输出:

  CATEGORY_ID       pnr         npk         jpg
  -----------      -----       -----       -----      
  Miscellaneous    1000         0           1000
  Local Travel     6000         3400        0

PROJECT 是动态的,可能会有所不同。

2 个答案:

答案 0 :(得分:1)

试试这个,它适用于SQL Server 2008:

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

SELECT @cols = STUFF((SELECT ',' + PROJECT
                    FROM (SELECT DISTINCT PROJECT FROM Table1 )sub
                   FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


SET @query = 'SELECT * FROM
                (
                SELECT CATEGORY_ID, PROJECT, AMOUNT 
                FROM Table1   
                --WHERE VOUCHER_DATE BETWEEN '' AND ''
                ) AS T1
                PIVOT (SUM(AMOUNT) FOR PROJECT IN ('+@cols+')) AS T2

'
EXEC(@query)

SQL Fiddle

基本上,您使用动态SQL来设置项目列表,因为它可以变化,然后按照惯例PIVOT,我注释了凭证日期标准,因为样本日期格式不正确。如果某些项目完全被日期要求排除,那么您还会将日期条件添加到设置项目列表的顶部。

答案 1 :(得分:0)

如果项目列的值已知并且它们也很少,您可以尝试:

select category_id
    ,sum(case when project='pnr' then amount else 0. end) as pnr
    ,sum(case when project='npk' then amount else 0. end) as npk
    ,sum(case when project='jpg' then amount else 0. end) as jpg
from [yourtable]
where [voucher date] between @bd and @ed--@bd and @ed are the input interval
group by category_id

或使用pivot命令

由于