2013-08-02 8 views
14

पर आधारित SQL सर्वर पिवोट एकाधिक कॉलम मेरे पास SQL ​​सर्वर 2008R2 में निम्न स्रोत और गंतव्य तालिकाएं हैं। स्रोत से गंतव्य तक पहुंचने के लिए मैं टीएसक्यूएल में पिवट कैसे कर सकता हूं।एक कॉलम

SourceTbl

empId empIndex empState empStDate empEndDate 
======================================================== 
10  1   AL   1/1/2012  12/1/2012 
10  2   FL   2/1/2012  2/1/2013 
15  1   FL   3/20/2012 1/1/2099 

DestTbl

empId empState1 empState1StDate empState1EndDt empState2 empState2StDate empState2EndDt 
========================================================================================================= 
10  AL   1/1/2012   12/1/2012   FL   2/1/2012   2/1/2013 
15  FL   3/20/2012   1/1/2099   NULL  NULL    NULL 

उम्मीद है कि किसी भी तरह empIndex धुरी में मदद मिलेगी।

+0

पिवट को msaccess में रूपांतरित करने के रूप में भी जाना जाता है। आपका प्रश्न अद्वितीय है कि इसके परिणामस्वरूप कोशिकाओं में टेक्स्ट (पूर्णांक नहीं) भी है। कुल फ़ंक्शन को अभी भी लागू करना होगा, इस मामले में MIN() को टेक्स्ट मानों पर ठीक करना चाहिए, भले ही केवल 1 टेक्स्ट मान हो। – hamish

उत्तर

23

चूंकि आप SQL सर्वर का उपयोग कर रहे हैं, इसलिए पंक्तियों को पंक्तियों में परिवर्तित करने के कई अलग-अलग तरीके हैं। तुम एक मामला अभिव्यक्ति के साथ एक समग्र समारोह का उपयोग कर सकते हैं:

select empid, 
    max(case when empindex = 1 then empstate end) empState1, 
    max(case when empindex = 1 then empStDate end) empStDate1, 
    max(case when empindex = 1 then empEndDate end) empEndDate1, 
    max(case when empindex = 2 then empstate end) empState2, 
    max(case when empindex = 2 then empStDate end) empStDate2, 
    max(case when empindex = 2 then empEndDate end) empEndDate2 
from sourcetbl 
group by empid; 

SQL Fiddle with Demo देखें।

आप धुरी समारोह का उपयोग करने के परिणाम प्राप्त करना चाहते हैं, तो मैं पहले कॉलम unpivoting सिफारिश करेंगे empState, empStDate और empEndDate ताकि आप एकाधिक पंक्तियों पहले होगा। आप UNPIVOT समारोह का उपयोग कर सकते या पार डेटा कन्वर्ट करने के लिए लागू कोड होगा:

select empid, col+cast(empindex as varchar(10)) col, value 
from sourcetbl 
cross apply 
(
    select 'empstate', empstate union all 
    select 'empstdate', convert(varchar(10), empstdate, 120) union all 
    select 'empenddate', convert(varchar(10), empenddate, 120) 
) c (col, value); 

Demo देखें। एक बार डेटा unpivoted है, तो आप धुरी समारोह लागू कर सकते हैं तो अंतिम कोड होगा:

select empid, 
    empState1, empStDate1, empEndDate1, 
    empState2, empStDate2, empEndDate2 
from 
(
    select empid, col+cast(empindex as varchar(10)) col, value 
    from sourcetbl 
    cross apply 
    (
    select 'empstate', empstate union all 
    select 'empstdate', convert(varchar(10), empstdate, 120) union all 
    select 'empenddate', convert(varchar(10), empenddate, 120) 
) c (col, value) 
) d 
pivot 
(
    max(value) 
    for col in (empState1, empStDate1, empEndDate1, 
       empState2, empStDate2, empEndDate2) 
) piv; 

SQL Fiddle with Demo देखें।

संस्करणों ऊपर

गु महान यदि आप empindex की एक सीमित संख्या है काम करेंगे, लेकिन यदि नहीं तो आप गतिशील एसक्यूएल का उपयोग कर सकते हैं:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(empindex as varchar(10))) 
        from SourceTbl 
        cross apply 
        (
         select 'empstate', 1 union all 
         select 'empstdate', 2 union all 
         select 'empenddate', 3 
        ) c (col, so) 
        group by col, so, empindex 
        order by empindex, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT empid,' + @cols + ' 
      from 
      (
       select empid, col+cast(empindex as varchar(10)) col, value 
       from sourcetbl 
       cross apply 
       (
        select ''empstate'', empstate union all 
        select ''empstdate'', convert(varchar(10), empstdate, 120) union all 
        select ''empenddate'', convert(varchar(10), empenddate, 120) 
       ) c (col, value) 
      ) x 
      pivot 
      (
       max(value) 
       for col in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

एसक्यूएल देखें Fiddle with Demo

आप सम्मिलित करना इन प्रश्नों का उपयोग कर सकते अपने DestTbl में, या इस प्रारूप में डेटा को संग्रहीत करने के बजाय, अब आपके पास वांछित परिणाम प्राप्त करने के लिए एक प्रश्न है।

इन क्वेरी प्रारूप में डेटा जगह:

| EMPID | EMPSTATE1 | EMPSTDATE1 | EMPENDDATE1 | EMPSTATE2 | EMPSTDATE2 | EMPENDDATE2 | 
--------------------------------------------------------------------------------------- 
| 10 |  AL | 2012-01-01 | 2012-12-01 |  FL | 2012-02-01 | 2013-02-01 | 
| 15 |  FL | 2012-03-20 | 2099-01-01 | (null) |  (null) |  (null) | 
+0

मैं आपके प्रयास की सराहना करता हूं। यह मेरी समस्या भी हल करता है। बहुत कुछ @bluefeet –

+0

मैंने एक्सएमएल के लिए बहुत पहले उपयोग किया है .. लेकिन कुडोस और * थंबस * का सबसे अच्छा उपयोग करने के लिए: STUFF QUOTENAME और NVARCHAR (MAX) PIVOT में :) MSACCESS इस ट्रांसफ़ॉर्म को कॉल करता है (सुनिश्चित नहीं है कि वह आदेश क्यों एसक्यूएल सर्वर को कभी नहीं बनाया) – hamish

-1

वाह, यह और अधिक जटिल की तुलना में मैं कल्पना की थी, लेकिन मैं यह बहुत अच्छा काम करने के लिए मिला! धन्यवाद। यह मेरा अंतिम संस्करण था। टेक्स्टकी में वह डेटा होता है जिसे आप कॉलम में बदलना चाहते हैं, और टेक्स्टवैल्यू वह मान है जो प्रत्येक सेल के अंदर समाप्त होता है।

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


select @cols = STUFF((SELECT distinct ', ' + QUOTENAME(TextKey) 
        from #SourceTbl 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT FromEntityID, DisplayName, ' + @cols + ' 
       FROM 
       (
        select FromEntityID, DisplayName, TextKey, TextValue 
        from #SourceTbl 
      ) x 
       pivot 
       (
        min(TextValue) 
        for TextKey in (' + @cols + ') 
      ) p 
       ORDER BY FromEntityID 
       ' 

execute(@query) 
संबंधित मुद्दे