3

SQL Server 2008を使用していて、このテーブルをクロス集計したい

Month   Affec   KPI     Total   KPI_%   Out     rep_in_10  ftm
Jan-11  30565   34623   42003   82.4    7380    7003       5024
Jan-12  20955   25915   27857   93      1942    4754       3518
Feb-11  27754   27757   36483   76.1    8726    5648       4189
Feb-12  19513   25188   26962   93.4    1774    5768       4185
Mar-11  22838   23758   29951   79.3    6193    4394       3282
Mar-12  18778   25098   26177   95.9    1079    5784       4105
Apr-11  20235   21950   25917   84.7    3967    3895       2967

            Jan-11  Jan-12  Feb-11  Feb-12  Mar-11  Apr-11
Affec       30565   
KPI         34623   
Total       42003   
KPI_%       82.4         
Out         7380    
rep_in_10   7003
4

3 に答える 3

1

私の意見では、これを行うべきではありません。これは、PHPまたは使用しているものを使用してプレゼンテーション層で簡単に実現できます。データベースは、データを適切にフォーマットするためではなく、データを取得するためにあります。概念実証として、Mahmoudの回答をもっと参照してください。ただし、クエリは、データを取得するために現在持っているクエリほど高速になることはありません。メンテナンスはそれに対する別の議論かもしれません。

于 2012-12-10T10:05:16.053 に答える
0

このような:

;WITH UNpivoted
AS
(
  SELECT MonthsValue, Value, month
  FROM (SELECT [Month], 
        CAST([Affec] AS VARCHAR(10)) Affec ,
        CAST([KPIprecent] AS VARCHAR(10)) KPIprecent,
        CAST([Total] AS VARCHAR(10)) Total, 
        CAST([KPI] AS VARCHAR(10)) KPI, 
        CAST([Out] AS VARCHAR(10)) [Out],
        CAST([rep_in_10] AS VARCHAR(10)) [rep_in_10], 
        CAST([ftm] AS VARCHAR(10)) ftm
        FROM table1
       ) t
  UNPIVOT
  (
    MonthsValue FOR Value IN([Affec], 
                             [KPIprecent], 
                             [Total], 
                             [KPI],        
                             [Out], 
                             [rep_in_10], 
                             [ftm])
  ) u
)
  SELECT
    value,
    [Jan-11], 
    [Jan-12], 
    [Feb-11], 
    [Feb-12],
    [Mar-11], 
    [Mar-12], 
    [Apr-11]
  FROM
  (
    SELECT monthsvalue, value, month
    FROM Unpivoted
  ) t
  PIVOT
  (MAX(monthsvalue) for Month IN ([Jan-11], 
                                 [Jan-12], 
                                 [Feb-11], 
                                 [Feb-12],
                                 [Mar-11], 
                                 [Mar-12], 
                                 [Apr-11])
  ) p;

SQL フィドルのデモ

これにより、次のことが得られます。

|      VALUE | JAN-11 | JAN-12 | FEB-11 | FEB-12 | MAR-11 | MAR-12 | APR-11 |
-----------------------------------------------------------------------------
|      Affec |  30565 |  20955 |  27754 |  19513 |  22838 |  18778 |  20235 |
|        ftm |   5024 |   3518 |   4189 |   4185 |   3282 |   4105 |   2967 |
|        KPI |   82.4 |   93.0 |   76.1 |   93.4 |   79.3 |   95.9 |   84.7 |
| KPIprecent |  34623 |  25915 |  27757 |  25188 |  23758 |  25098 |  21950 |
|        Out |   7380 |   1942 |   8726 |   1774 |   6193 |   1079 |   3967 |
|  rep_in_10 |   7003 |   4754 |   5648 |   5768 |   4394 |   5784 |   3895 |
|      Total |  42003 |  27857 |  36483 |  26962 |  29951 |  26177 |  25917 |
于 2012-12-10T09:58:14.737 に答える
0

このタイプのデータ変換では、関数を使用してから、SQL Server で関数をUNPIVOT適用する必要があります。PIVOT

これを実行するには 2 つの方法があります。動的 SQL を使用して実行時に値を生成する静的バージョンで値をハードコーディングする方法です。

静的バージョン:

このUNPIVOT部分は、複数の列からデータを取得し、2 つの行に変換します。unpivot で注意すべき点は、データ型が同じでなければならないということです。そのため、データに対してデータ型変換を実行する必要がある場合があります。:

select [Month], value, col
from
(
  select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
    [Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm]
  from yourtable
) src
unpivot
(
  value
  for col in ([Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm])
) unpiv

デモで SQL Fiddle を参照してください

結果:

|         MONTH | VALUE |       COL |
-------------------------------------
|  January-2011 | 30565 |     Affec |
|  January-2011 | 34623 |       KPI |
|  January-2011 | 42003 |     Total |
|  January-2011 |  82.4 |     KPI_% |
|  January-2011 |  7380 |       Out |  ---etc

次に、 を月に適用しますPIVOT

select *
from
(
  select [Month], value, col
  from
  (
    select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
      [Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm]
    from yourtable
  ) src
  unpivot
  (
    value
    for col in ([Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm])
  ) unpiv
) src
pivot
(
  max(value)
  for month in ([January-2011], [February-2011], [March-2011],
             [April-2011], [January-2012], [February-2012], [March-2012])
) piv

デモで SQL Fiddle を参照してください

結果:

|       COL | JANUARY-2011 | FEBRUARY-2011 | MARCH-2011 | APRIL-2011 | JANUARY-2012 | FEBRUARY-2012 | MARCH-2012 |
------------------------------------------------------------------------------------------------------------------
|     Affec |        30565 |         27754 |      22838 |      20235 |        20955 |         19513 |      18778 |
|       ftm |         5024 |          4189 |       3282 |       2967 |         3518 |          4185 |       4105 |
|       KPI |        34623 |         27757 |      23758 |      21950 |        25915 |         25188 |      25098 |
|     KPI_% |         82.4 |          76.1 |       79.3 |       84.7 |           93 |          93.4 |       95.9 |
|       Out |         7380 |          8726 |       6193 |       3967 |         1942 |          1774 |       1079 |
| rep_in_10 |         7003 |          5648 |       4394 |       3895 |         4754 |          5768 |       5784 |
|     Total |        42003 |         36483 |      29951 |      25917 |        27857 |         26962 |      26177 |

動的バージョン:

上記はうまく機能します。値の数がわかっているが、値が不明な場合は、動的SQLを使用する必要があります。日付の数が不明であるため、動的バージョンが必要になると思います。

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

select @colsUnpivot = STUFF((SELECT DISTINCT ',' 
                      + quotename(c.name)
                    from sys.columns as C
                   where C.object_id = object_id('yourtable') and
                         C.name not in ('Month')
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @cols = STUFF((SELECT ',' + QUOTENAME(DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4))) 
                    from yourtable
                    group by [Month]
                    order by [Month]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT col,' + @cols + ' from 
             (
               select [Month], value, col
              from
              (
                select DateName(month,[Month]) +''-''+Cast(datepart(year, [month]) as varchar(4)) Month,
                  [Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm]
                from yourtable
              ) src
              unpivot
              (
                value
                for col in ('+@colsunpivot+')
              ) unpiv
            ) x
            pivot
            (
              max(value)
              for [Month] in (' + @cols + ')
            ) p '

execute(@query)

デモで SQL Fiddle を参照してください

結果は動的バージョンと同じになります。

集約を使用した UNION ALL/CASE:

UNPIVOT最後に、またはPIVOT関数のいずれにもアクセスできない場合は、 を使用してピボットを解除し、 を使用しUNION ALLて集計関数を使用しCASEてデータをピボットできます。

select col,
  max(case when month='January-2011' then value end) [January-2011],
  max(case when month='February-2011' then value end) [February-2011],
  max(case when month='March-2011' then value end) [March-2011],
  max(case when month='April-2011' then value end) [April-2011],
  max(case when month='January-2012' then value end) [January-2012],
  max(case when month='February-2012' then value end) [February-2012],
  max(case when month='March-2012' then value end) [March-2012]
from
(
  select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
    [Affec] value,
    'Affec' col
  from yourtable
  union all
  select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
    [KPI] value,
    'KPI' col
  from yourtable
  union all
  select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
    [Total] value,
    'Total' col
  from yourtable
  union all
  select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
    [KPI_%] value,
    'KPI_%' col
  from yourtable
  union all
  select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
    [rep_in_10] value,
    'rep_in_10' col
  from yourtable
  union all
  select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
    [ftm] value,
    'ftm' col
  from yourtable
) src
group by col

デモで SQL Fiddle を参照してください

于 2012-12-10T10:07:21.690 に答える