2012-10-27 20 views
8

Ho una tabella per i profili memorizza profili valori proprietà in stile fila, ex:T: SQL: selezionare i valori di righe come colonne

[ProfileID]  [PropertyDefinitionID]  [PropertyValue] 
1    6       Jone 
1    7       Smith 
1    8       Mr 
1    3       50000 

e un altro tavolo per definizioni di proprietà:

[PropertyDefinitionID] [PropertyName] 
6      FirstName 
7      LastName 
8      Prefix 
3      Salary 

Come usare PIVOT o in qualsiasi altro modo per mostrare in questo modo:

[ProfileID] [FirstName] [LastName] [Salary] 
1   Jone  Smith  5000 

risposta

11

e 'facile fare questo senza 012.346.parola chiave, semplicemente raggruppando

select 
    P.ProfileID, 
    min(case when PD.PropertyName = 'FirstName' then P.PropertyValue else null end) as FirstName, 
    min(case when PD.PropertyName = 'LastName' then P.PropertyValue else null end) as LastName, 
    min(case when PD.PropertyName = 'Salary' then P.PropertyValue else null end) as Salary 
from Profiles as P 
    left outer join PropertyDefinitions as PD on PD.PropertyDefinitionID = P.PropertyDefinitionID 
group by P.ProfileID 

si può anche fare questo con PIVOT parola chiave

select 
    * 
from 
(
    select P.ProfileID, P.PropertyValue, PD.PropertyName 
    from Profiles as P 
     left outer join PropertyDefinitions as PD on PD.PropertyDefinitionID = P.PropertyDefinitionID 
) as P 
    pivot 
    (
     min(P.PropertyValue) 
     for P.PropertyName in ([FirstName], [LastName], [Salary]) 
    ) as PIV 

UPDATE: Per il numero dinamica di proprietà - dare un'occhiata a Increment value in SQL SELECT statement

+0

Grazie per il vostro contributo, entrambi i metodi hanno risolto questo problema, tuttavia se prendiamo in considerazione le prestazioni, quale è più veloce? – Alaa

5

Sembra potresti avere un numero sconosciuto di PropertyName's che devi trasformare in colonne. Se questo è il caso, allora è possibile utilizzare SQL dinamico per generare il risultato:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(PropertyName) 
        from propertydefinitions 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT profileid, ' + @cols + ' from 
      (
       select p.profileid, 
        p.propertyvalue, 
        d.propertyname 
       from profiles p 
       left join propertydefinitions d 
        on p.PropertyDefinitionID = d.PropertyDefinitionID 
      ) x 
      pivot 
      (
       max(propertyvalue) 
       for propertyname in (' + @cols + ') 
      ) p ' 

execute(@query) 

Vedi SQL Fiddle with Demo.

+0

non è necessario usare 'for xml' quando hai solo bisogno di concatenare colonne in variabili. Potrebbero esserci anche problemi di sicurezza quando si tenta di selezionare i dati dalla tabella, ad esempio, l'utente può disporre delle autorizzazioni per la procedura, ma non ha autorizzazioni sulle tabelle. Dai un'occhiata alla mia risposta qui - http://stackoverflow.com/questions/13055295/increment-value-in-sql-select-statement/13055403#13055403 –

+1

@RomanPekar ci sono vari modi per concatenare le colonne, questo è il metodo che scelgo di usare. – Taryn

Problemi correlati