T-SQL 循环中多次自连接

T-SQL Multiple self-joins in a loop

我有一个 table,它在单个列中包含字段集合,我正在尝试将其构造为正确查看它自己行中的每个字段,如下例所示:

T_data:
  +------+---------+---------+
  | ID   | Field   | Value   |
  +------+---------+---------+
  | 1    | Name    | John    |
  | 1    | Age     | 41      |
  | 1    | Height  | 181     |
  | 2    | Name    | Kelly   |
  | 2    | Age     | 42      |
  | 2    | Height  | 165     |
  | 3    | Name    | Dan     |
  | 3    | Age     | 43      |
  | 3    | Height  | 169     |
  +------+---------+---------+

T_result:
  +--------+--------+--------+--------+
  | Name   | John   | Kelly  | Dan    |
  | Age    | 41     | 42     | 43     |
  | Height | 181    | 165    | 169    |
  +--------+--------+--------+--------+

我知道如何在同一个 table 上有 3 个自连接的示例中执行此操作,但这只是一个简化的示例,我的数据将有一个 ID 和字段的未知数量 - 我需要以某种方式遍历它们并将它们加入动态 table。 我将如何达到我的结果?

这是我的想法(行不通):

  with #T_id as (
  select distinct ID, row_number() over (order by ID asc) as rn form T_data )

  -- here's where I need to loop through the IDs
  -- Pseudo-code ... I know the following doesn't work

  while @i <= (select count(*) from #T_id)
  begin
    select T_data.Field, T_data.Value from T_data
    left join T_result on T_data.Field = T_result.Field
    where T_data.ID = (select ID from #T_id where rn = @i)
  end

编辑:最终结果是供 Reports Server 使用的存储过程。

任何帮助将不胜感激:)

PIVOT 很棒,但我使用动态数据透视的存储过程

Exec [prc-Pivot] 'YourTable','ID','max(Value)[]','Field','count(*)[Records]'

Returns

Field   Records 1     2       3
Age     3       41    42      43
Height  3       181   165     169
Name    3       John  Kelly   Dan

存储过程

CREATE PROCEDURE [dbo].[prc-Pivot] (
    @Source varchar(1000),          -- Any Table or Select Statement
    @PvotCol varchar(250),          -- Field name or expression ie. Month(Date)
    @Summaries varchar(250),        -- aggfunction(aggValue)[optionalTitle]
    @GroupBy varchar(250),          -- Optional additional Group By 
    @OtherCols varchar(500) )       -- Optional Group By or aggregates
AS

--Exec [prc-Pivot] 'Select Year=Year(TR_Date),* From [Chinrus-Series].[dbo].[DS_Treasury_Rates]','''Q''+DateName(QQ,TR_Date)','avg(TR_Y10)[-Avg]','Year','count(*)[Records],min(TR_Y10)[Min],max(TR_Y10)[Max],Avg(TR_Y10)[Avg]'
--Exec [prc-Pivot] '#Temp','Attribute','max(Description)[]','ID','count(*)[Records]'

Set NoCount On
Set Ansi_Warnings Off

Declare @Vals varchar(max),@SQL varchar(max);
Set @Vals = ''
Set @OtherCols= IsNull(', ' + @OtherCols,'')
Set @Source = case when @Source Like 'Select%' then @Source else 'Select * From '+@Source end
Create Table #TempPvot  (Pvot varchar(100))
Insert Into #TempPvot
Exec ('Select Distinct Convert(varchar(100),' + @PvotCol + ') as Pvot FROM (' + @Source + ') A')
Select @Vals = @Vals + ', isnull(' + Replace(Replace(@Summaries,'(','(CASE WHEN ' + @PvotCol + '=''' + Pvot +  ''' THEN '),')[', ' END),0) As [' + Pvot ) From #TempPvot Order by Pvot
Drop Table #TempPvot
Set @SQL = Replace('Select ' + Isnull(@GroupBy,'') + @OtherCols + @Vals + ' From (' + @Source + ') PvtFinal ' + case when Isnull(@GroupBy,'')<>'' then 'Group By ' + @GroupBy + ' Order by ' + @GroupBy else '' end,'Select , ','Select ')
--Print @SQL
Exec (@SQL)


Set NoCount Off
Set Ansi_Warnings on

枢轴 + 动态 SQL:

CREATE PROCEDURE dbo.ProcedureName
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @cols nvarchar(max),
            @sql nvarchar(max)

    SELECT @cols =COALESCE(@cols,'') +','+  QUOTENAME(ID) --,[1],[2],[3]
    FROM T_data
    GROUP BY ID

    SET @sql = N'
    SELECT *
    FROM T_data
    PIVOT (
        MAX([Value]) FOR ID IN ('+STUFF(@cols,1,1,'')+')
    ) as dd'


    EXEC sp_executesql @sql

END

输出:

Field   1       2       3
-------------------------------
Age     41      42      43
Height  181     165     169
Name    John    Kelly   Dan