2016-06-15 2 views
0

У меня проблема с преобразованием строк в столбцы SQL-результата.SQL Pivot без агрегации

Моя структура такова:

GUID | PropertyName | PropertyValue

abcd | DistinguishedName | cn = abcd ...

abcd | CN | cn = GROUP_

abcd | Операция | ADD

1231 | DistinguishedName | cn = 123dd

1231 | Cn | cn = ASDGRUOP

1231 | Операция | DEL

Может существовать n имен свойств, которые я не знаю прежде, они динамически - я могу получить их через SQL, это не проблема.

Я хочу, чтобы у вас была такая структура: GUID | DistinguishedName | CN | Операция

abcd | сп = ABCD ... | cn = GROUP_ | ADD

1231 | cn = 123dd | cn = ADSGROUP | DEL

и так далее.

колонного Заголовки я получаю от этого SQL:

select @cols = STUFF ((SELECT DISTINCT '],[' + x.ParameterName from ... and parametername in ('PropertyValue','DistinguishedName', 'Operation') 
FOR XML PATH ('')),1,2,'') + ']' 

Я могу сделать это с помощью PIVOT-функции, но потому, что я не имею Aggregation, я не могу получить правильный результат:

set @query = N'SELECT '+ @cols + ' FROM (
    SELECT x.parametervalue, x.parametername 
    from ... and parametername in (''PropertyValue'',''DistinguishedName'', ''Operation'') 
    ) a 
    PIVOT (max(a.parametervalue) FOR ParameterName in (' + @cols + ')) as pv;' 
exec sp_executesql @query; 

Я получаю следующий результат:

GUID | DistinguishedName | CN | Операция | ... другие объекты недвижимости

abcd | cn = abcd ... | cn = GROUP_ | ADD | ...

Только 1 Результат - не более. Но, как и 700 результатов этого запроса, из-за функции MAX() я получаю только один. Как я могу получить Pivot без агрегации, чтобы получить все результаты?

Спасибо вам заранее!

+0

Трудно помочь без использования * полного * примера. Вы близки. Вам просто нужно убедиться, что * resultset *, который вы поворачиваете, включает в себя столбец «GUID», а также каждый из столбцов «parameter», так как операция 'PIVOT' всегда производит одну строку * на * отдельный набор значения для столбцов в наборе результатов, которые * не являются * частью 'PIVOT'. –

ответ

1

Вот динамический PIVOT запрос:

DECLARE @sql NVARCHAR(MAX), 
     @cols NVARCHAR(MAX); 

SELECT @cols = 
    STUFF((
     SELECT DISTINCT ',' + QUOTENAME(PropertyName) 
     FROM #tbl 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    , 1, 1, '') 

SELECT @sql = 
'SELECT GUID, ' + @cols + ' 
FROM (
    SELECT 
     GUID, PropertyName, PropertyValue 
    FROM #tbl 
) t 
PIVOT 
(
    MAX(PropertyValue) 
    FOR PropertyName IN(' + @cols + ') 
) p '; 

PRINT (@sql); 
EXEC (@sql); 

ONLINE DEMO


Другой способ достичь желаемого результата состоит в использовании dynamic crosstab:

DECLARE @sql NVARCHAR(MAX); 

SELECT @sql = 
'SELECT 
    GUID' + CHAR(10) + 
(SELECT DISTINCT 
' , MAX(CASE WHEN PropertyName = ''' + PropertyName + ''' THEN PropertyValue END) AS ' + QUOTENAME(PropertyName) + CHAR(10) 
FROM #tbl 
FOR XML PATH('') 
) + 
'FROM #tbl 
GROUP BY GUID;'; 

PRINT (@sql); 
EXEC (@sql); 

ONLINE DEMO

+1

ist Работа! Большое спасибо за быстрый и блестящий ответ! – Phil

+0

Единственная проблема: я должен выполнить этот SQL в редакторе отчетов, и эта программа не знает команду EXECUTE SP_EXECUTESQL. Как преобразовать запрос так, чтобы он выполнялся без этой команды? – Phil