2013-08-08 8 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 

इसके बजाय, मैं यह चाहते हैं इस तरह देखने के लिए:

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 

अतीत में, मैंने बस अपने डेटा में आवश्यक फ़ील्ड_आईडी की तलाश करने का प्रयास किया और प्रत्येक के लिए केस स्टेटमेंट बनाए। उपयोगकर्ता द्वारा उपयोग किए जा रहे ऐप में कई उत्पादों के लिए डेटा शामिल है, और प्रत्येक उत्पाद में अलग-अलग फ़ील्ड होते हैं। समर्थित उत्पादों की संख्या और प्रत्येक उत्पाद के लिए फ़ील्ड की संख्या को ध्यान में रखते हुए (कई, ऊपर दिखाए गए मूल उदाहरण से कहीं अधिक) उन्हें देखने के लिए लंबा समय लगता है और केस विवरणों के विशाल भाग लिखते हैं।

मैं सोच रहा था कि फ़ील्ड_ड्स को देखने और चीजों को लिखने के बिना मुझे जो कुछ चाहिए, उसे प्राप्त करने के लिए वहां कुछ धोखा-कोड है या नहीं। मुझे पता है कि 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 के लिए मानों की संख्या ज्ञात नहीं है करने के लिए जा रहे हैं, तो आप गतिशील एसक्यूएल को लागू करने के परिणाम प्राप्त करने की आवश्यकता होगी:

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; 

देखें। इन दोनों ने इस एक परिणाम दे देंगे:

| 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

यह मैं वास्तव में क्या जरूरत है।मेरे पास आपको ऊपर उठाने का प्रतिनिधि नहीं है, लेकिन यदि यहां कोई और व्यक्ति इसे देखता है, तो कृपया मेरे लिए ऊपर उठो! –

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; 
संबंधित मुद्दे