2016-08-16 2 views
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 

편집 : 최종 결과는 의미 저장 프로 시저가 보고서 서버 사용할 수 있도록합니다.

어떤 도움을

+1

구글의 SQL 서버의 동적 피벗 '. 그것은 당신을 시작해야합니다. – 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