表格数据采用某种格式

时间:2013-11-27 21:52:07

标签: asp.net sql gridview pivot

我正在尝试获取此格式的数据

Tname   FY  FPY Week
test1   87  78  1
test1   45  34  2
test1   34  89  3
test1   34  56  4
test1   56  78  5
test1   68  45  6
test2   45  89  1
test2   76  65  2
test2   45  54  3
test3   56  57.8    2
test4   34  55  4
test4   32  52.2    7
test3   78  49.4    3
test5   89  46.6    2
test5   90  43.8    1
test5   98  41  6
test5   91  38.2    7
test6   92  35.4    5
test6   93  32.6    6

显示结果

Tname   week1       Week2       Week3       Week4       Week5       Week6       Week7   
    FY  FPY FY  FPY FY  FPY FY  FPY FY  FPY FY  FPY FY  FPY
test1   87  78  45  34  34  89  34  56  56  78  68  45  NULL    NULL
test2   45  89  76  65  45  54  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
test3   NULL    NULL    56  57.8    78  49.4    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
test4   NULL    NULL    NULL    NULL    NULL    NULL    34  55  NULL    NULL    NULL    NULL    32  52.2
test5   90  43.8    89  46.6    NULL    NULL    NULL    NULL    NULL    NULL    98  41  91  38.2
test6   NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    92  35.4    93  32.6    NULL    NULL

我想使用存储过程或gridview实现此目的。请指教

2 个答案:

答案 0 :(得分:1)

您没有具体说明您使用的是哪种RDBMS,但之前的问题是使用SQL Server标记的,因此这个答案假定您使用的是数据库。

有几种方法可以获得结果。一种简单的方法是使用具有类似于:

的CASE表达式的聚合函数
select tname,
  sum(case when week = 1 then FY end) Week1FY,
  sum(case when week = 1 then FPY end) Week1FPY,
  sum(case when week = 2 then FY end) Week2FY,
  sum(case when week = 2 then FPY end) Week2FPY,
  sum(case when week = 3 then FY end) Week3FY,
  sum(case when week = 3 then FPY end) Week3FPY,
  sum(case when week = 4 then FY end) Week4FY,
  sum(case when week = 4 then FPY end) Week4FPY,
  sum(case when week = 5 then FY end) Week5FY,
  sum(case when week = 5 then FPY end) Week5FPY,
  sum(case when week = 6 then FY end) Week6FY,
  sum(case when week = 6 then FPY end) Week6FPY,
  sum(case when week = 7 then FY end) Week7FY,
  sum(case when week = 7 then FPY end) Week7FPY
from yourtable
group by tname;

请参阅SQL Fiddle with Demo

由于您需要在两列上进行PIVOT,因此您将首先取消FYFPY列中数据的取消操作,然后应用PIVOT函数。再次取决于您的RDBMS,有几种方法可以显示数据我将使用CROSS APPLY和UNION ALL显示如何执行此操作:

select tname, 
  col = 'week_'+cast(week as varchar(2))+'_'+col, 
  value
from yourtable
cross apply
(
  select 'FY', FY union all
  select 'FPY', FPY 
) c (col, value)

unpivot进程将您的数据从多列转换为多行:

| TNAME |        COL | VALUE |
|-------|------------|-------|
| test1 |  week_1_FY |    87 |
| test1 | week_1_FPY |    78 |
| test1 |  week_2_FY |    45 |
| test1 | week_2_FPY |    34 |
| test1 |  week_3_FY |    34 |

然后你可以应用PIVOT功能:

select tname,
  week_1_FY, week_1_FPY, week_2_FY, week_2_FPY,
  week_3_FY, week_3_FPY, week_4_FY, week_4_FPY,
  week_5_FY, week_5_FPY, week_6_FY, week_6_FPY,
  week_7_FY, week_7_FPY
from
(
  select tname, 
    col = 'week_'+cast(week as varchar(2))+'_'+col, 
    value
  from yourtable
  cross apply
  (
    select 'FY', FY union all
    select 'FPY', FPY 
  ) c (col, value)
) d
pivot
(
  sum(value)
  for col in (week_1_FY, week_1_FPY, week_2_FY, week_2_FPY,
              week_3_FY, week_3_FPY, week_4_FY, week_4_FPY,
              week_5_FY, week_5_FPY, week_6_FY, week_6_FPY,
              week_7_FY, week_7_FPY)
) piv;

SQL Fiddle with Demo

最后,如果周数不明,那么您可以使用动态SQL来获得结果:

DECLARE @cols AS NVARCHAR(MAX),
  @query  AS NVARCHAR(MAX),
  @weekstart int = 1,
  @weekend int = 4

select @cols = STUFF((SELECT ',' + QUOTENAME('week_'+cast(week as varchar(2))+'_'+col) 
                    from yourtable
                    cross apply
                    (
                      select 'FY', 1 union all
                      select 'FPY', 2
                    ) c (col, so)
                    where week >= @weekstart
                        and week <= @weekend
                    group by col, so, week
                    order by week, so
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT tname, ' + @cols + ' 
            from 
            (
              select tname, 
                col = ''week_''+cast(week as varchar(2))+''_''+col, 
                value
              from yourtable
              cross apply
              (
                select ''FY'', FY union all
                select ''FPY'', FPY 
              ) c (col, value)
              where week >= '+cast(@weekstart as varchar(2))+'
                and week <= '+cast(@weekend as varchar(2))+'
            ) x
            pivot 
            (
                sum(value)
                for col in (' + @cols + ')
            ) p '

execute sp_executesql @query;

SQL Fiddle with Demo。所有版本的结果都是:

| TNAME | WEEK_1_FY | WEEK_1_FPY | WEEK_2_FY | WEEK_2_FPY | WEEK_3_FY | WEEK_3_FPY | WEEK_4_FY | WEEK_4_FPY | WEEK_5_FY | WEEK_5_FPY | WEEK_6_FY | WEEK_6_FPY | WEEK_7_FY | WEEK_7_FPY |
|-------|-----------|------------|-----------|------------|-----------|------------|-----------|------------|-----------|------------|-----------|------------|-----------|------------|
| test1 |        87 |         78 |        45 |         34 |        34 |         89 |        34 |         56 |        56 |         78 |        68 |         45 |    (null) |     (null) |
| test2 |        45 |         89 |        76 |         65 |        45 |         54 |    (null) |     (null) |    (null) |     (null) |    (null) |     (null) |    (null) |     (null) |
| test3 |    (null) |     (null) |        56 |         58 |        78 |         49 |    (null) |     (null) |    (null) |     (null) |    (null) |     (null) |    (null) |     (null) |
| test4 |    (null) |     (null) |    (null) |     (null) |    (null) |     (null) |        34 |         55 |    (null) |     (null) |    (null) |     (null) |        32 |         52 |
| test5 |        90 |         44 |        89 |         47 |    (null) |     (null) |    (null) |     (null) |    (null) |     (null) |        98 |         41 |        91 |         38 |
| test6 |    (null) |     (null) |    (null) |     (null) |    (null) |     (null) |    (null) |     (null) |        92 |         35 |        93 |         33 |    (null) |     (null) |

答案 1 :(得分:0)

尝试类似

的内容
SELECT *
FROM (
    SELECT TName, [1] as Week1FY, [2] as Week2FY, [3] as Week3FY, 
        [4] as Week4FY, [5] as Week5FY, [6] as Week6FY, [7] as Week7FY
    FROM( SELECT t.TName, t.FY, t.Week FROM Table t
    PIVOT
        ( MAX(FY) FOR Week in ([1], [2], [3], [4], [5], [6], [7])
    )) as P
    JOIN
    (
    SELECT TName, [1] as Week1FPY, [2] as Week2FPY, [3] as Week3FPY,
        [4] as Week4FPY, [5] as Week5FPY, [6] as Week6FPY, [7] as Week7FPY
    FROM( SELECT t.TName, t.FPY, t.Week FROM Table t
    PIVOT
        ( MAX(FPY) FOR Week in ([1], [2], [3], [4], [5], [6], [7])
    )) as Q ON P.TName = Q.TName