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

SQL Server 2012 PIVOT bez agregatu

Istnieje kilka sposobów przekształcania danych. Niektórzy używają funkcji agregującej, a inni nie. Ale nawet jeśli przestawiasz łańcuch, nadal możesz zastosować agregację.

Agregacja z CASE:

select name,
  max(case when category = 'A' then 'X' else '' end) CategoryA,
  max(case when category = 'B' then 'X' else '' end) CategoryB,
  max(case when category = 'C' then 'X' else '' end) CategoryC,
  max(case when category = 'D' then 'X' else '' end) CategoryD
from yourtable 
group by name

Zobacz Skrzypce SQL z wersją demonstracyjną

Statyczny obrót:

Nadal możesz używać PIVOT funkcja przekształcania danych, nawet jeśli wartości są ciągami. Jeśli masz znaną liczbę kategorii, możesz na stałe zakodować zapytanie:

select name, 
  coalesce(A, '') CategoryA, 
  coalesce(B, '') CategoryB, 
  coalesce(C, '') CategoryC, 
  coalesce(C, '') CategoryD
from
(
  select name, category, 'X' flag
  from yourtable
) d
pivot
(
  max(flag)
  for category in (A, B, C, D)
) piv

Zobacz Skrzypce SQL z wersją demonstracyjną .

Dynamiczny obrót:

Jeśli masz nieznaną liczbę kategorii, możesz użyć dynamicznego SQL:

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

select @cols = STUFF((SELECT  ',' + QUOTENAME(category) 
                    from yourtable
                    group by category
                    order by category
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT  ', coalesce(' + QUOTENAME(category)+', '''') as '+QUOTENAME('Category'+category)
                    from yourtable
                    group by category
                    order by category
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT name, ' + @colsNull + ' 
              from 
             (
                select name, category, ''X'' flag
                from yourtable
            ) x
            pivot 
            (
                max(flag)
                for category in (' + @cols + ')
            ) p '

execute(@query)

Zobacz SQL Fiddle z wersją demonstracyjną .

Połączenia wielokrotne:

select c1.name,
  case when c1.category is not null then 'X' else '' end as CategoryA,
  case when c2.category is not null then 'X' else '' end as CategoryB,
  case when c3.category is not null then 'X' else '' end as CategoryC,
  case when c4.category is not null then 'X' else '' end as CategoryD
from yourtable c1
left join yourtable c2
  on c1.name = c2.name
  and c2.category = 'B'
left join yourtable c3
  on c1.name = c3.name
  and c3.category = 'C'
left join yourtable c4
  on c1.name = c4.name
  and c4.category = 'D'
where c1.category = 'A'

Zobacz Skrzypce SQL z wersją demonstracyjną

Wszystkie zapytania dadzą wynik:

| NAME | CATEGORYA | CATEGORYB | CATEGORYC | CATEGORYD |
--------------------------------------------------------
|  Joe |         X |         X |           |         X |
| Mary |         X |           |         X |         X |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SSMS 2016 Błąd podczas importowania Azure SQL v12 bacpac:klucze główne bez hasła nie są obsługiwane

  2. Problem z instrukcją CASE w procedurze składowanej serwera sql

  3. Jakie możliwości MS SQL Server są podobne do funkcji MySQL FIELD()?

  4. Zapytanie ODBC na MS SQL Server zwracające pierwsze 255 znaków tylko w PHP PDO (FreeTDS)

  5. Zapytanie, jak dodać brakujące daty w sql