2013-08-08 4 views
13

이 항목에 대해 다른 질문을 제출해 죄송합니다. 그러나이 질문에 대한 많은 답변을 읽었으며 제대로 작동하지 않는 것으로 보입니다.SQL Server 2008 가로 데이터 세로

나는 세 개의 테이블을 가지고있어 정보를 얻고 싶다. 테이블 중 하나는 3 열이며 데이터를 수직으로 저장합니다. 이 데이터를 가로 형식으로 바꾸고 싶습니다.

SELECT 
    a.app_id, 
    b.field_id, 
    c.field_name, 
    b.field_value 
FROM table1 a 
JOIN table2 b ON a.app_id = b.app_id 
JOIN table3 c ON b.field_id = c.field_id --(table3 is a lookup table for field names) 

결과 : 대신

app_id | field_id | field_name | field_value 
----------------------------------------------------- 
1234 | 101  | First Name |  Joe 
1234 | 102  |  Last Name |  Smith 
1234 | 105  |  DOB  | 10/15/72 
1234 | 107  | Mailing Addr | PO BOX 1234 
1234 | 110  |  Zip  |  12345  
1239 | 101  | First Name |  Bob 
1239 | 102  |  Last Name |  Johnson 
1239 | 105  |  DOB  | 12/01/78 
1239 | 107  | Mailing Addr | 1234 N Star Ave 
1239 | 110  |  Zip  |  12456 

, I는 다음과 같이 그것을 싶습니다

app_id | First Name | Last Name | DOB | Mailing Addr | Zip 
-------------------------------------------------------------------------- 
1234 | Joe  |  Smith  | 10/15/72 | PO BOX 1234 | 12345  
1239 | Bob  | Johnson | 12/01/78 | 1234 N Star Ave | 12456 
난 그냥 가입하고 당기면

데이터는 다음과 같이 표시됩니다

과거에는 필자가 데이터에서 필요로하는 모든 field_id를 조사하고 각각에 대해 CASE 문을 만들었습니다. 사용자가 사용중인 앱에는 여러 제품에 대한 데이터가 있으며 각 제품에는 다른 필드가 있습니다. 지원되는 제품의 수와 각 제품의 필드 수를 고려하면 (위의 기본 예제보다 더 많이 많음)이를 찾아 보면서 CASE 문을 거대한 덩어리로 작성하는 데 시간이 오래 걸립니다.

field_ids를보고 물건을 쓰지 않고도 필요한 것을 달성 할 수있는 치트 코드가 있는지 궁금합니다. 나는 PIVOT 함수가 내가 찾고있는 가능성이 높다는 것을 알고 있지만 제대로 작동하지는 못합니다.

사람들이 도와 줄 수 있다고 생각하십니까?

답변

29

당신은 컬럼에 데이터의 당신의 행을 변환 할 PIVOT 기능을 사용할 수 있습니다보십시오.

원래 쿼리를 사용하여 모든 데이터를 검색 할 수 있으며 결과의 최종 표시가 변경되므로 b.field_id 열을 제외하는 것이 유일한 변경 사항입니다.

select app_id, 
    [First Name], [Last Name], [DOB], 
    [Mailing Addr], [Zip] 
from 
(
    SELECT 
    a.app_id, 
    c.field_name, 
    b.field_value 
    FROM table1 a 
    INNER JOIN table2 b 
    ON a.app_id = b.app_id 
    INNER JOIN table3 c 
    ON b.field_id = c.field_id 
) d 
pivot 
(
    max(field_value) 
    for field_name in ([First Name], [Last Name], [DOB], 
        [Mailing Addr], [Zip]) 
) piv; 

SQL Fiddle with Demo를 참조하십시오 : 당신은 당신이 열로 전환 할 field_name 값, 알려진 목록이있는 경우

당신은 하드 코드 조회를 할 수 있습니다. 당신이 field_name 값의 알 수없는 번호를 가지고가는 경우

그러나, 당신은 결과를 얻기 위해 동적 SQL을 구현해야합니다

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(Field_name) 
        from Table3 
        group by field_name, Field_id 
        order by Field_id 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT app_id,' + @cols + ' 
      from 
      (
       SELECT 
       a.app_id, 
       c.field_name, 
       b.field_value 
       FROM table1 a 
       INNER JOIN table2 b 
       ON a.app_id = b.app_id 
       INNER JOIN table3 c 
       ON b.field_id = c.field_id 
      ) x 
      pivot 
      (
       max(field_value) 
       for field_name in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

SQL Fiddle with Demo를 참조하십시오.

| APP_ID | FIRST NAME | LAST NAME |  DOB | MAILING ADDR | ZIP | 
------------------------------------------------------------------------ 
| 1234 |  Joe |  Smith | 10/15/72 |  PO Box 1234 | 12345 | 
| 1239 |  Bob | Johnson | 12/01/78 | 1234 N Star Ave | 12456 | 
+4

이 내가 필요 정확히이다.나는 당신을 상향 조정할 담당자가 없지만, 여기있는 다른 누군가가 이것을보고 있으면, 나를 위해 upvote하십시오! –

3

SELECT 
    [app_id] 
    ,MAX([First Name]) AS [First Name] 
    ,MAX([Last Name]) AS [Last Name] 
    ,MAX([DOB]) AS [DOB] 
    ,MAX([Mailing Addr]) AS [Mailing Addr] 
    ,MAX([Zip]) AS [Zip] 
FROM Table1 
PIVOT 
(
    MAX([field_value]) FOR [field_name] IN ([First Name],[Last Name],[DOB],[Mailing Addr],[Zip]) 
) T 
GROUP BY [app_id] 

SQL FIDDLE DEMO

0

bluefeet의 대답은 나를 위해 올바른 하나,하지만 난 열 목록에 별개의 필요 : 다음이 모두 결과를 줄 것이다

DECLARE @cols AS NVARCHAR(MAX), 
@query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT Distinct ',' + QUOTENAME(Field_name) 
       from Table3 
       group by field_name, Field_id 
       order by ',' + QUOTENAME(Field_name) 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 

set @query = 'SELECT app_id,' + @cols + ' 
     from 
     (
      SELECT 
      a.app_id, 
      c.field_name, 
      b.field_value 
      FROM table1 a 
      INNER JOIN table2 b 
      ON a.app_id = b.app_id 
      INNER JOIN table3 c 
      ON b.field_id = c.field_id 
     ) x 
     pivot 
     (
      max(field_value) 
      for field_name in (' + @cols + ') 
     ) p ' 

execute sp_executesql @query;