Sql 编写用于将行拉入列而不进行聚合的查询会混淆列,而不是按顺序列出它们

Sql 编写用于将行拉入列而不进行聚合的查询会混淆列,而不是按顺序列出它们,sql,sql-server,sql-server-2014,Sql,Sql Server,Sql Server 2014,TL;DR:大约有1800个函数被转换为“pivot”列,但它们并没有按顺序被调用,因此函数_376总是先被调用,然后是“random”其他函数,而且并非所有角色都有那么多函数,而且它会导致空值。如何让它按顺序拉动函数 我正在尝试创建一个查询,以生成一个结果集,该结果集可以以人类可读的方式轻松复制并粘贴到Excel中。我的查询中的正常结果集包含两列,即role和function,每对都有一行。我的目标是把所有的功能放在同一行上,并为分配给角色的每个功能设置一列。我所得到的最接近的结果是重新利用我

TL;DR:大约有1800个函数被转换为“pivot”列,但它们并没有按顺序被调用,因此函数_376总是先被调用,然后是“random”其他函数,而且并非所有角色都有那么多函数,而且它会导致空值。如何让它按顺序拉动函数

我正在尝试创建一个查询,以生成一个结果集,该结果集可以以人类可读的方式轻松复制并粘贴到Excel中。我的查询中的正常结果集包含两列,即role和function,每对都有一行。我的目标是把所有的功能放在同一行上,并为分配给角色的每个功能设置一列。我所得到的最接近的结果是重新利用我在中找到的脚本,但我遇到的问题是返回结果的查询混淆了列。它没有按顺序行、function1、function2等返回它们,结果是带有空值,这使得输出实际上毫无用处。每次我运行@cols查询时,它都会以一致的顺序将函数拉到一起,但不是以数字顺序,它看起来是随机的。每个Function\u 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)

我解决了!这显然是朝着正确的方向点头。我还需要另一个临时表来计算最大列数,然后我使用一个变量将其传递到第一个stuff函数中。见下文:

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)

问题在于distinct,它不维护订单请将解决方案作为答案发布,然后接受它,以便帮助其他有类似问题的用户