如何根据sql中的行选择动态列数

时间:2015-11-19 07:03:57

标签: sql sql-server

我有以下数据

Activity         | Indicator          | Impact
------------------------------------------------
Payroll risk     | Indicator A        | Low
Payroll risk     | Indicator B        | Low
Payroll risk     | Indicator C        | Low
Wrong selections | Indicator D        | High
Wrong selections | Indicator E        | High
Fraudulant Cred  | Indicator F        | Medium
Fraudulant Cred  | Indicator G        | Medium

然后应按以下格式接收此数据

Activity         | Indicator   | Indicator   | Indicator   | Impact
--------------------------------------------------------------------
Payroll risk     | Indicator A | Indicator B | Indicator C | Low
Wrong selections | Indicator D | Indicator E |             | High
Fraudulant cred  | Indicator F | Indicator G |             | Medium

在sql中进行以下操作的过程是什么? 列的数量与任何常见记录的最大行数相同。

感谢。

3 个答案:

答案 0 :(得分:1)

你可以使用CASE或PIVOT来做到这一点。以下是样本数据的Pivot示例:

SELECT Activity, Impact, [1], [2], [3]

FROM (
SELECT Activity, Indicator, Impact
,ROW_NUMBER()OVER(PARTITION BY Activity ORDER BY Indicator) AS R
FROM @T
) AS M
PIVOT
(
MAX(Indicator)
FOR R IN ([1], [2], [3])
) P

如果您想动态执行此操作,请参阅:Dynamic PIVOT in SQL Server

答案 1 :(得分:1)

一种方法 -

select 
  Activity
, [Indicator] = max(case when RowID = 1 then Indicator end)
, [Indicator] = max(case when RowID = 2 then Indicator end)
, [Indicator] = max(case when RowID = 3 then Indicator end)
,Impact
from (
select 
    Activity
  , Indicator
  , Impact
  , RowID = row_number() over (partition by Impact order by Activity)
  from #PIVOT
)
SourceTable
group by Activity,Impact

答案 2 :(得分:1)

要使用动态sql,您需要先找出最大列数,然后创建这些数字的列表。然后使用查询的单词创建一个字符串变量,并弹出您创建的列名字符串。我在下面的例子中调用了你的表RiskImpacts

以下是如何找出所需的列数,并将其存储在变量@maxcount

declare @maxcount int;
select @maxcount = max(indcount) 
from (select [Activity],count([Indicator]) as indcount 
      from RiskImpacts group by activity
     ) as countindicators;

接下来,您需要根据该数字创建一个列名称字符串。我们将它存储在@columnnames中:

declare @columnnames nvarchar(max)
set @columnnames = ''
select @columnnames = @columnnames + '[Indicator ' + cast(ROW_NUMBER() over (order by indicator) as nvarchar(50)) + '],' from 
(select top (@maxcount-1) * from RiskImpacts) as a

set @columnnames = @columnnames +'[Indicator ' + cast(@maxcount as nvarchar(50)) + ']'

除了最后一个用逗号结尾之外的所有内容,然后添加到最后一个。 @columnnames现在看起来像这样:

[Indicator 1],[Indicator 2],[Indicator 3]

现在我们可以将它们放在一个字符串中,以创建我们想要运行的查询。

declare @pivotsql nvarchar(max)
set @pivotsql= 'select Activity, ' + @columnnames + ', Impact
    from ( select Activity, Indicator, Impact, ''Indicator '' + cast(ROW_NUMBER()OVER(PARTITION BY Activity ORDER BY Indicator) as nvarchar(50)) as R
            from RiskImpacts
         ) as M
    pivot
        ( max(Indicator) for R in (' + @columnnames + ')
        ) P'

最后我们需要执行那段SQL

exec (@pivotsql)