Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

wiersze w kolumny

W przypadku tego typu danych musisz zaimplementować zarówno UNPIVOT a następnie PIVOT funkcje SQL Server. UNPIVOT pobiera dane z wielu kolumn i umieszcza je w dwóch kolumnach, a następnie stosujesz PIVOT aby przekształcić dane z powrotem w kolumny.

Jeśli znasz wszystkie wartości, które chcesz przekształcić, możesz je zakodować na stałe, podobnie do tego:

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

Zobacz Skrzypce SQL z wersją demonstracyjną

Teraz, jeśli masz nieznaną liczbę wartości do przekształcenia, możesz użyć do tego dynamicznego 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('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)

Zobacz Skrzypce SQL z wersją demonstracyjną

Wynik obu zapytań to:

| 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. Czy szybciej jest UAKTUALNIĆ wiersz, czy USUNĄĆ go i WSTAWIĆ nowy?

  2. Zapytania międzybazowe z różnymi nazwami baz danych w różnych środowiskach?

  3. Jak naprawić „wyrażenie EXECUTE nie powiodło się, ponieważ jego klauzula WITH RESULT SETS określiła 1 zestaw wyników…” w programie SQL Server

  4. Idealna burza do uaktualnienia do nowoczesnej wersji SQL Server

  5. znajdź zmienną długość dla typu danych serwera sql nvarchar z kodu c#