Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

hàng thành cột

Đối với loại dữ liệu này, bạn sẽ cần triển khai cả UNPIVOT và sau đó là PIVOT các chức năng của SQL Server. UNPIVOT lấy dữ liệu của bạn từ nhiều cột và đặt nó thành hai cột và sau đó bạn áp dụng PIVOT để chuyển đổi dữ liệu trở lại thành các cột.

Nếu bạn biết tất cả các giá trị mà bạn muốn chuyển đổi, thì bạn có thể mã hóa nó, tương tự như sau:

select *
from
(
  select value, col+'_'+cast(rn as varchar(10)) col
  from
  (
    select nvrchildname,
      nvrgender,
      convert(varchar(10), dttchildDOB, 120) dttchildDOB,
      occupation,
      row_number() over(partition by intsid order by intCHID) rn
    from tblHRIS_ChildDetails
    where intsid = 463
  ) src
  unpivot
  (
    value 
    for col in (nvrchildname, nvrgender, dttchildDOB, occupation)
  ) unpiv
) src1
pivot
(
  max(value)
  for col in ([nvrchildname_1], [nvrgender_1], 
              [dttchildDOB_1], [occupation_1], 
              [nvrchildname_2], [nvrgender_2], 
              [dttchildDOB_2], [occupation_2]) 
) piv

Xem SQL Fiddle với Demo

Bây giờ, nếu bạn có một số lượng giá trị chưa biết để chuyển đổi, thì bạn có thể sử dụng SQL động cho việc này:

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('tblHRIS_ChildDetails') and
               C.name not in ('intCHID', 'intsid')
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(c.name 
                         +'_'+ cast(t.rn as varchar(10)))
                    from 
                    (
                      select row_number() over(partition by intsid order by intCHID) rn
                      from tblHRIS_ChildDetails
                    ) t
                    cross apply sys.columns as C
                   where C.object_id = object_id('tblHRIS_ChildDetails') and
                         C.name not in ('intCHID', 'intsid')
                   group by c.name, t.rn
                   order by t.rn
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'select *
      from
      (
        select col+''_''+cast(rn as varchar(10)) col, value
        from 
        (
          select nvrchildname,
            nvrgender,
            convert(varchar(10), dttchildDOB, 120) dttchildDOB,
            occupation,
            row_number() over(partition by intsid order by intCHID) rn
          from tblHRIS_ChildDetails
          where intsid = 463
        ) x
        unpivot
        (
          value
          for col in ('+ @colsunpivot +')
        ) u
      ) x1
      pivot
      (
        max(value)
        for col in  ('+ @colspivot +')
      ) p'

exec(@query)

Xem SQL Fiddle với Demo

Kết quả của cả hai truy vấn là:

| NVRCHILDNAME_1 | NVRGENDER_1 | DTTCHILDDOB_1 | OCCUPATION_1 | NVRCHILDNAME_2 | NVRGENDER_2 | DTTCHILDDOB_2 | OCCUPATION_2 |
-----------------------------------------------------------------------------------------------------------------------------
|             SK |      Female |    2001-12-11 |     Studying |             SM |        Male |    2007-10-08 |      Student |


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL - Hạn chế số lượng hàng được trả về dựa trên số lượng hàng

  2. Làm cách nào để tôi có thể dễ dàng san bằng hệ thống phân cấp Máy chủ Sql này thành một danh sách bao gồm được kế thừa?

  3. Cách hiệu quả nhất để di chuyển các hàng trong bảng từ bảng này sang bảng khác

  4. Làm cách nào để tính số ngày chủ nhật sáu tuần bằng cách sử dụng Weekno trong SQL Server 2008?

  5. Thủ tục được lưu trữ trong SQL Server (thứ tự theo mô tả)?