-1

我有表 Tbl_Login

Cat_ID 整数
金额 1 小数
金额 2 小数
金额 3 小数
日期日期


Cat_ID Amount1 Amount2 Amount3 日期
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
我想输入两个日期 12/02/2013 15/02/2013 和

列 1 Cat_ID 12-02-2013 13-02-2013 14-02-2013 15-02-2013
金额1 1 10 20 null null    
金额 2 1 12 22 null null
金额 3 1 12 22 null null    

金额1 2 10 20 null null    
金额 2 2 12 22 null null
金额 3 2 12 22 null null    

金额1 3 10 20 null null    
金额2 3 12 22 null null
金额 3 3 12 22 null null    

金额1 4 10 null null null    
金额 2 4 12 null null null
金额 3 4 12 null null null    

金额1 5 null 20 null null    
金额 2 5 无 22 无 无
金额 3 5 无 22 无 无  

4

1 回答 1

4

您没有指定您使用的是什么 RDBMS,但是您可以通过多种方式将此数据转换为您需要的结果。

如果您使用的数据库没有PIVOT函数,那么这可以通过使用UNION ALL查询来取消透视数据,然后使用带有CASE表达式的聚合函数将日期透视到列中来完成。查询将与此类似:

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

请参阅带有演示的 SQL Fiddle

如果您使用的是 SQL Server 2005+ 或 Oracle 11g+,那么您可以同时使用UNPIVOTPIVOT函数:

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

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

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)

请参阅带有演示的 SQL Fiddle

所有查询的结果是:

|     COL | CAT_ID | 2013-02-12 | 2013-02-13 | 2013-02-14 | 2013-02-15 |
------------------------------------------------------------------------
| 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) |
于 2013-02-15T16:29:00.010 回答