sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server 2012 PIVOT utan aggregat

Det finns flera sätt att omvandla data. Vissa använder en aggregerad funktion och andra inte. Men även om du pivoterar en sträng kan du fortfarande använda ett aggregat.

Aggregera med 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

Se SQL-fiol med demo

Statisk pivot:

Du kan fortfarande använda PIVOT funktion för att transformera data trots att värdena är strängar. Om du har ett känt antal kategorier kan du hårdkoda frågan:

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

Se SQL-fiol med demo .

Dynamisk pivot:

Om du har ett okänt antal kategorier kan du använda dynamisk 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)

Se SQL-fiol med demo .

Flera anslutningar:

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'

Se SQL-fiol med demo

Alla frågor ger resultatet:

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



  1. PHP &MySQL:mysqli_num_rows() förväntar sig att parameter 1 är mysqli_result, boolean given

  2. MYSQL LEFT JOIN-optimering med CASE

  3. Effektiv övervakning av MySQL med SCUMM Dashboards:Del 3

  4. Hur man grupperar efter 1 i SQL Server