1

次のようなデータがあります。

 MaGiangVienID  |  SoTiet1  |  SoTiet2  |  DateID
79000G07.000206 |      60   |    60.00  |     t11
79000G07.000206 |      54   |    54.00  |     t12

私はこのように私の結果をしたい:

 MaGiangVienID  | SoTiet1_t11 | SoTiet2_t11 | SoTiet1_t12 | SoTiet2_t12
79000G07.000206 |          60 |       60.00 |          54 |       54.00

MaGiangVienIDたくさんあるので、列の数はわかりませんDateID

助けてください!!どうもありがとう。

4

1 に答える 1

2

このタイプのデータ変換では、関数UNPIVOTPIVOT関数の両方を適用する必要があります。はUNPIVOT複数の列からデータを取得して行に配置し、次に行を取得してPIVOT列に変換します。

UNPIVOT行に変換するすべての値を実行するには、同じデータ型でなければならないため、変換が必要になる場合があります。

アンピボット:

select MaGiangVienID, 
    value, 
    col +'_'+DateId col
from
(
  select MaGiangVienID, 
    cast(SoTiet1 as varchar(50)) SoTiet1, 
    cast(SoTiet2 as varchar(50)) SoTiet2,
    DateID
  from yourtable
) src
unpivot
(
  value
  for col in (SoTiet1, SoTiet2)
) unpiv

SQL Fiddle with Demoを参照してください。アンピボットの結果は次のとおりです。

|   MAGIANGVIENID | VALUE |         COL |
-----------------------------------------
| 79000G07.000206 |    60 | SoTiet1_t11 |
| 79000G07.000206 | 60.00 | SoTiet2_t11 |
| 79000G07.000206 |    54 | SoTiet1_t12 |
| 79000G07.000206 | 54.00 | SoTiet2_t12 |

ご覧のとおり、末尾に が追加されUNPIVOTた新しい列名が生成されます。DateId次に、関数を適用しPIVOTます。

静的ピボット:

select MaGiangVienID, SoTiet1_t11, SoTiet2_t11, SoTiet1_t12, SoTiet2_t12
from
(
  select MaGiangVienID, 
    value, 
    col +'_'+DateId col
  from
  (
    select MaGiangVienID, 
      cast(SoTiet1 as varchar(50)) SoTiet1, 
      cast(SoTiet2 as varchar(50)) SoTiet2,
      DateID
    from yourtable
  ) src
  unpivot
  (
    value
    for col in (SoTiet1, SoTiet2)
  ) unpiv
) src
pivot
(
  max(value)
  for col in (SoTiet1_t11, SoTiet2_t11, SoTiet1_t12, SoTiet2_t12)
) piv

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

上記のバージョンは、既知の数のDateId値がある場合にうまく機能しますが、そうではないと述べたので、動的SQLを使用してこの同じクエリを実装する必要があります。

動的ピボット:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yourtable') and
               C.name not in ('MaGiangVienID', 'DateID')
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT DISTINCT ',' 
                      + quotename(c.name + '_'+t.DateId)
                    from yourtable t
                    cross apply sys.columns as C
                   where C.object_id = object_id('yourtable') and
                         C.name not in ('MaGiangVienID', 'DateID')

            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'select MaGiangVienID, '+@colsPivot+'
      from
      (
          select MaGiangVienID, value, col +''_''+DateId col
          from
          (
            select MaGiangVienID, 
              cast(SoTiet1 as varchar(50)) SoTiet1, 
              cast(SoTiet2 as varchar(50)) SoTiet2,
              DateID
            from yourtable
          ) src
          unpivot
          (
            value
            for col in ('+@colsUnpivot+')
          ) unpiv
      ) src
      pivot
      (
        max(value)
        for col in ('+ @colspivot +')
      ) p'

exec(@query)

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

どちらのバージョンでも同じ結果が得られます。

結果は次のとおりです。

|   MAGIANGVIENID | SOTIET1_T11 | SOTIET2_T11 | SOTIET1_T12 | SOTIET2_T12 |
---------------------------------------------------------------------------
| 79000G07.000206 |          60 |       60.00 |          54 |       54.00 |

UNPIVOT/PIVOT関数にアクセスできない場合は、クエリを複製できます。関数はUNPIVOTを使用して複製でき、集約関数を含むステートメントを使用しUNION ALLPIVOT生成できます。CASE

select MaGiangVienID,
  max(case when col = 'SoTiet1_t11' then value end) SoTiet1_t11,
  max(case when col = 'SoTiet2_t11' then value end) SoTiet2_t11,
  max(case when col = 'SoTiet1_t12' then value end) SoTiet1_t12,
  max(case when col = 'SoTiet2_t12' then value end) SoTiet2_t12
from
(
  select MaGiangVienID, 'SoTiet1_t11' col, cast(SoTiet1 as varchar(50)) value
  from yourtable
  where DateID = 't11'
  union all
  select MaGiangVienID, 'SoTiet2_t11' col, cast(SoTiet2 as varchar(50)) value
  from yourtable
  where DateID = 't11'
  union all
  select MaGiangVienID, 'SoTiet1_t12' col, cast(SoTiet1 as varchar(50)) value
  from yourtable
  where DateID = 't12'
  union all
  select MaGiangVienID, 'SoTiet2_t12' col, cast(SoTiet2 as varchar(50)) value
  from yourtable
  where DateID = 't12'
) src
group by MaGiangVienID

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

すべてのバージョンで同じ結果が得られます。

于 2013-01-04T10:36:35.280 に答える