2016-08-16 9 views
1

フィールドのコレクションを1つの列に含むテーブルがあります。次のように、それ自身の行の各フィールドの適切なビューに構築しようとしています例:T-SQLループ内の複数の自己結合

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 | 
    +--------+--------+--------+--------+ 

私は3自己との例でこれを行う方法を知っているが、同じテーブルに合流するが、これは単なる簡略化した例である、私のデータは、IDとフィールドの未知数を持っています - 私は何とかそれらをループし、動的なテーブルにそれらを結合する必要があります。 私の結果に到達するにはどうすればいいですか?

これは一種-の私は心の中で持っているもの(動作しない)である:

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のが使用するストアドプロシージャのためのものです。

すべてのヘルプは理解されるであろう:)

+1

グーグルのSQL Serverの動的ピボット "。それはあなたを始めるはずです。 – dfundako

+0

テーブルから属性を無制限に読み込むためにSQLを生成しようとしているようですが、このSQLを生成するためにSQLを使用しますか(SQLでSQLを生成してからSQLを実行できますか?プログラミング言語のSQLコマンド?別のアプローチは、データを読み込んで一時テーブルに挿入し、最後に一時テーブルを照会するループまたはカーソルを作成することです。または、PIVOTテーブルを探していますか?これを行うことができれば最高に見えるでしょう – Cato

答えて

1

PIVOTは素晴らしいですが、私は

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

戻り

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 '[email protected] 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 
ダイナミックピボットのためのストアドプロシージャを使用
0

PIVOT +動的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