sql >> Databasteknik >  >> RDS >> Sqlserver

Transponera rader och kolumner utan aggregat

Om du ska använda PIVOT funktion, du kommer att behöva använda en aggregerad funktion för att få resultatet men du vill också använda en fönsterfunktion som row_number() för att generera en unik sekvens för varje kontakt i kontot.

Först kommer du att fråga efter dina uppgifter som liknar:

select account, contact,
  'contact'
    + cast(row_number() over(partition by account
                              order by contact) as varchar(10)) seq
from yourtable

Se SQL Fiddle with Demo. Detta skapar en ny kolumn med den unika sekvensen:

| ACCOUNT |   CONTACT |      SEQ |
|---------|-----------|----------|
|       1 | 324324324 | contact1 |
|       1 | 674323234 | contact2 |

Om du har ett begränsat antal kolumner kan du hårdkoda din fråga:

select account,
  contact1, contact2, contact3, contact4
from 
(
  select account, contact,
    'contact'
      + cast(row_number() over(partition by account
                                order by contact) as varchar(10)) seq
  from yourtable
) d
pivot
(
  max(contact)
  for seq in (contact1, contact2, contact3, contact4)
) piv;

Se SQL Fiddle with Demo

Om du har ett okänt antal kolumner måste du använda dynamisk SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(seq) 
                    from
                    (
                      select 'contact'
                              + cast(row_number() over(partition by account
                                                        order by contact) as varchar(10)) seq
                      from yourtable
                    ) d
                    group by seq
                    order by seq
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT account, ' + @cols + ' 
            from 
            (
                select account, contact,
                  ''contact''
                    + cast(row_number() over(partition by account
                                              order by contact) as varchar(10)) seq
                from yourtable
            ) x
            pivot 
            (
                max(contact)
                for seq in (' + @cols + ')
            ) p '

execute sp_executesql @query;

Se SQL Fiddle with Demo. Båda ger dig ett resultat av:

| ACCOUNT |  CONTACT1 |  CONTACT2 |  CONTACT3 |  CONTACT4 |
|---------|-----------|-----------|-----------|-----------|
|       1 | 324324324 | 674323234 |    (null) |    (null) |
|       2 | 433243443 | 833343432 |    (null) |    (null) |
|       3 | 787655455 |    (null) |    (null) |    (null) |
|       4 | 455435435 | 754327545 |    (null) |    (null) |
|       5 | 432432432 | 432433242 | 432455553 | 543544355 |


  1. Force Oracle Drop Global Temp-tabell

  2. Den lagrade proceduren för att hämta instansinställningarna

  3. Kör batchfil med psql-kommandot utan lösenord

  4. Ska jag indexera primärnyckelkolumner i Oracle