Запрос, написанный для вытягивания строк в столбцы без агрегирования, приводит к путанице в столбцах, а не к их перечислению по порядку. - PullRequest
0 голосов
/ 07 июня 2018

TL; DR: около 1800 функций превращаются в столбцы для "pivot", но они не вызываются по порядку, так что function_376 последовательно вызывается сначала, а затем "случайными" другими, и не все роли имеют столько функций, и это тянетобнуляет.Как заставить его вытащить функции по порядку?

Я пытаюсь создать запрос для создания набора результатов, который можно легко скопировать и вставить в Excel в удобочитаемой форме.Обычный набор результатов из моего запроса извлекает два столбца, роль и функцию, со строкой для каждой отдельной пары.Моя цель - перенести все функции в одну строку и иметь столбец для каждой функции, назначенной роли.Самое близкое, что я получил, - это перепрофилирование сценария, который я нашел в этом ответе , но проблема, с которой я сталкиваюсь, заключается в том, что запрос на возврат результатов приводит в замешательство столбцы.Он не возвращает их в строке порядка, function1, function2 и т. Д. И, как результат, связан с NULL, что делает вывод практически бесполезным.Запрос @cols объединяет функции в последовательном порядке каждый раз, когда я запускаю его, но он не в числовом порядке, он кажется случайным.Каждый столбец Function_N представляет N-ую функцию, связанную с ролью, поэтому, если бы я мог получить запрос @cols для построения по порядку, то это сработало бы.

Как я могу переписать это так, чтобы в выводе были перечислены функциив числовом порядке, чтобы результаты были выровнены по левому краю?

Код и снимок экрана результатов показаны ниже.

IF OBJECT_ID('tempdb.dbo.#roles', 'U') IS NOT NULL
  DROP TABLE #roles;

CREATE TABLE #roles([role] VARCHAR(MAX), [function] VARCHAR(MAX))
Insert into #roles 
select distinct r.r_desc, f.f_desc
from roles r
join role_functions rf on rf_rid = r_id
join Functions f on f_id = rf_fid
where r.r_Active = 'y'


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

select @cols = STUFF((SELECT distinct ',' 
                      + QUOTENAME(rn) 
                    from
                    (
                      select 'function_'+cast(row_number() over(partition by [role] 
                                order by [role]) as varchar(20)) rn
                      from #roles
                    ) src
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT [Role],' + @cols + ' from 
             (
                select [Role], [function],
                  ''function_''+cast(row_number() over(partition by [role] 
                                              order by [role]) as varchar(20)) rn
                from #roles
            ) x
            pivot 
            (
                max([function])
                for rn in (' + @cols + ')
            ) p '

execute(@query)

Изображение результатов

1 Ответ

0 голосов
/ 26 июня 2018

Я решил это!Отличным был кивок в правильном направлении.Мне также нужна была другая временная таблица для расчета максимального количества столбцов, а затем я использовал переменную, чтобы передать это в первую функцию вещи.Смотрите ниже:

IF OBJECT_ID('tempdb.dbo.#roles', 'U') IS NOT NULL
  DROP TABLE #roles;


  IF OBJECT_ID('tempdb.dbo.#funtcnt', 'U') IS NOT NULL
  DROP TABLE #funtcnt;



CREATE TABLE #roles([role] VARCHAR(MAX), [function] VARCHAR(MAX))
Insert into #roles 
select distinct r.r_desc, f.f_desc
from roles r
join role_functions rf on rf_rid = r_id
join Functions sf on f_id = rf_fid
where r.r_Active = 'y'

select [role], count([function]) as [count]
INTO #funtcnt
from #roles  group by [role]

declare @topcount varchar(max) = (select top 1 [role] from #funtcnt order by [count] desc)



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

select @cols = STUFF((SELECT  ',' 
                      + QUOTENAME(rn) 
                    from
                    (
                      select 'function_'+cast(row_number() over(partition by [role] 
                                order by [role]) as varchar(20)) rn
                      from #roles where [role] = @topcount
                    ) src
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT [Role],' + @cols + ' from 
             (
                select [Role], [function],
                  ''function_''+cast(row_number() over(partition by [role] 
                                              order by [role]) as varchar(20)) rn
                from #roles
            ) x
            pivot 
            (
                max([function])
                for rn in (' + @cols + ')
            ) p '

execute(@query)
...