数据透视表连接在sql中

时间:2013-02-15 16:23:05

标签: sql pivot-table

我有桌子Tbl_Login

Cat_ID int 
Amount1 decimal 
Amount2 decimal
Amount3 decimal 
dateon date


Cat_ID Amount1 Amount2 Amount3  dateon
1   10  12  12  2013-02-12 
2   10  12  12  2013-02-12 
3   10  12  12  2013-02-12 
4   10  12  12  2013-02-12 

1   20  22  22  2013-02-13 
2   20  22  22  2013-02-13 
3   20  22  22  2013-02-13 
5   20  22  22  2013-02-13 
I want To Mamber Enter Two Date 12/02/2013 15/02/2013 and

colum1  Cat_ID  12-02-2013 13-02-2013   14-02-2013  15-02-2013
Amount1 1       10      20      null        null    
Amount2 1       12      22      null        null
Amount3 1       12      22      null        null    

Amount1 2       10      20      null        null    
Amount2 2       12      22      null        null
Amount3 2       12      22      null        null    

Amount1 3       10      20      null        null    
Amount2 3       12      22      null        null
Amount3 3       12      22      null        null    

Amount1 4       10      null    null        null    
Amount2 4       12      null    null        null
Amount3 4       12      null    null        null    

Amount1 5       null        20      null        null    
Amount2 5       null        22      null        null
Amount3 5       null        22      null        null  

1 个答案:

答案 0 :(得分:4)

您没有指定您正在使用的RDBMS,但有几种方法可以将此数据转换为您需要的结果。

如果您使用的数据库没有PIVOT函数,则可以使用UNION ALL查询来取消数据的转换,然后使用{{1的聚合函数表达式将日期转换为列。查询将类似于:

CASE

请参阅SQL Fiddle with Demo

如果您使用的是SQL Server 2005+或Oracle 11g +,则可以同时使用select col, cat_id, max(case when dateon = '2013-02-12' then value end) [2013-02-12], max(case when dateon = '2013-02-13' then value end) [2013-02-13], max(case when dateon = '2013-02-14' then value end) [2013-02-14], max(case when dateon = '2013-02-15' then value end) [2013-02-15] from ( select cat_id, 'amount1' col, amount1 value, dateon from tbl_login where dateon >= '2013-02-12' and dateon <= '2013-02-15' union all select cat_id, 'amount2' col, cast(amount2 as decimal(10,2)) value, dateon from tbl_login where dateon >= '2013-02-12' and dateon <= '2013-02-15' union all select cat_id, 'amount3' col, cast(amount3 as decimal(10,2)) value, dateon from tbl_login where dateon >= '2013-02-12' and dateon <= '2013-02-15' ) src group by col, cat_id order by cat_id, col UNPIVOT功能:

PIVOT

请参阅SQL Fiddle with Demo

如果您要将未知数量的日期转换为列,则可以使用动态sql(注意:动态代码是sql server语法):

select col, cat_id,
  [2013-02-12], [2013-02-13], 
  [2013-02-14], [2013-02-15]
from
(
  select cat_id, dateon,
    col, value
  from
  (
    select cat_id, amount1, 
      cast(amount2 as decimal(10,2)) amount2, 
      cast(amount3 as decimal(10,2)) amount3, 
      dateon
    from tbl_login
    where dateon >= '2013-02-12'
      and dateon <= '2013-02-15'
  ) s
  unpivot
  (
    value
    for col in (Amount1, Amount2, Amount3)
  ) unpiv
) src
pivot
(
  max(value)
  for dateon in ([2013-02-12], [2013-02-13], 
                 [2013-02-14], [2013-02-15])
) piv
order by cat_id, col

请参阅SQL Fiddle with Demo

所有查询的结果是:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @startdate datetime,
    @enddate datetime

set @startdate  ='2013-02-12'
set @enddate  ='2013-02-15'

;with dates (dt) as
(
  select @startdate
  union all
  select dateadd(dd, 1, dt)
  from dates
  where dateadd(dd, 1, dt) <= @enddate
)
select dt
into #temp
from dates

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(varchar(10), dt, 120)) 
                    from #temp
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT col, cat_id,' + @cols + ' 
            from
            (
              select cat_id, dateon,
                col, value
              from
              (
                select cat_id, amount1, 
                  cast(amount2 as decimal(10,2)) amount2, 
                  cast(amount3 as decimal(10,2)) amount3, 
                  dateon
                from tbl_login
                where dateon >= '''+convert(varchar(10), @startdate, 120)+'''
                  and dateon <= '''+convert(varchar(10), @enddate, 120)+'''
              ) s
              unpivot
              (
                value
                for col in (Amount1, Amount2, Amount3)
              ) unpiv
            ) src
            pivot
            (
              max(value)
              for dateon in (' + @cols + ')
            ) p 
            order by cat_id, col'

execute(@query)