2013-10-22 15 views
13

मेरे पास डेटाबेस में एक सारणी है जिसमें 9 कॉलम समान डेटा हैं, ये मान शून्य होने की अनुमति है। मुझे प्रत्येक गैर-शून्य मानों को उन मानों के एक स्तंभ में चुनने की आवश्यकता है, जिनकी उत्पत्ति की पंक्ति की पहचान परवाह नहीं है।एकाधिक स्तंभों से एकल कॉलम में मानों का चयन करें

तो, एक मेज है कि इस तरह दिखता है के लिए:

+---------+------+--------+------+ 
| Id | I1 | I2  | I3 | 
+---------+------+--------+------+ 
| 1 | x1 | x2  | x7 | 
| 2 | x3 | null | x8 | 
| 3 | null | null | null| 
| 4 | x4 | x5  | null| 
| 5 | null | x6  | x9 | 
+---------+------+--------+------+ 

मैं एक एकल स्तंभ में मान एक्स के साथ उपसर्ग से प्रत्येक का चयन करना चाहते हैं। मेरा परिणामी डेटा निम्न तालिका की तरह दिखना चाहिए। आदेश संरक्षित किए जाने की जरूरत है, तो पहली पंक्ति से पहले स्तंभ मान ऊपर और नीचे अंतिम पंक्ति से अंतिम स्तंभ मूल्य पर होना चाहिए: आर 2 मैं एसक्यूएल सर्वर 2008 का उपयोग कर रहा

+-------+ 
| value | 
+-------+ 
| x1 | 
| x2 | 
| x7 | 
| x3 | 
| x8 | 
| x4 | 
| x5 | 
| x6 | 
| x9 | 
+-------+ 

। क्या प्रत्येक कॉलम के मूल्य को प्रत्येक पंक्ति से, और परिणामों में गैर-शून्य मानों को सम्मिलित करने के बजाय इसे प्राप्त करने के लिए एक बेहतर तकनीक है?

उत्तर

17

आप अंतिम परिणाम प्राप्त करने के लिए UNPIVOT फ़ंक्शन का उपयोग कर सकते हैं:

select value 
from yourtable 
unpivot 
(
    value 
    for col in (I1, I2, I3) 
) un 
order by id, col; 

आप एसक्यूएल सर्वर 2008 + है, तो आप कर सकते हैं का उपयोग कर रहे के बाद से कॉलम को अनपिन करने के लिए VALUES क्लॉज के साथ क्रॉस लागू करें:

select value 
from yourtable 
cross apply 
(
    values 
     ('I1', I1), 
     ('I2', I2), 
     ('I3', I3) 
) c(col, value) 
where value is not null 
order by id, col 
+8

यहां ध्यान देने योग्य महत्वपूर्ण बात यह है कि, [वर्तमान में सबसे ज्यादा वोट वाले उत्तर] (http://stackoverflow.com/a/19515927/61305) के विपरीत, ये पूर्ण तालिका स्कैन की संख्या को कम करता है (1 बनाम 3)। और यदि आपके पास 5 कॉलम, या 8 कॉलम या 22 कॉलम थे, तो दोनों उस संख्या में स्कैन की संख्या बढ़ाते हैं, और क्वेरी के यूनियन संस्करण को लिखने/देखने के लिए और अधिक बोझिल बनाता है। –

5
SELECT value FROM (
    SELECT ID, 1 AS col, I1 AS [value] FROM t 
    UNION ALL SELECT ID, 2, I2 FROM t 
    UNION ALL SELECT ID, 3, I3 FROM t 
) AS t WHERE value IS NOT NULL ORDER BY ID, col; 
2

कोशिश यूनियन नीचे की तरह:

select value from 
(
    select col1 as value from TestTable 
    union 
    select col2 as value from TestTable 
    union 
    select col3 as value from TestTable 
) tt where value is not null 
संबंधित मुद्दे