2010-09-15 14 views
8

मैं डेटापंक्तियों से गतिशील कॉलम बनाने के लिए क्वेरी डिजाइन करने के लिए कैसे

Table1

ID  Name 
----------- 
1  n1 
2  n2 
3  n4 

तालिका 2

FID YearS Val 
---------------------- 
1  2008  Up 
1  2009  Down 
1  2010  Up 
2  2000  Up 
2  2001  Down 
2  2002  Up 
2  2003  Up 
3  2009  Down 
3  2010  Up 

मैं निम्न स्वरूप में डेटा वापस करना चाहते हैं:

ID Yr1 Val1 Yr2 Val2 Yr3 Val3 Yr4 Val4 
-------------------------------------------------------- 
1 2008 Up  2009 Down 2010 Up  NULL Null 
2 2000 Up  2001 Down 2002 Up  2003 Up 
3 2009 Down 2010 Up NULL NULL NULL Null 

अधिकतम के आधार पर आईडी के लिए कॉलम में से कोई भी मैं कॉलम नाम बनाना चाहता हूं और फिर पंक्तियों में पंक्तियों को परिवर्तित करना चाहता हूं। क्या एसक्यूएल क्वेरी का उपयोग करना संभव है?

+0

रिपोर्ट बनाने के लिए रिपोर्ट बिल्डर का उपयोग करें! –

+0

क्या कोई कारण है कि वर्ष के कॉलम का नाम रखने के बजाय प्रति वर्ष दो कॉलम क्यों होंगे? इस तरह आपके सभी वर्षों को समूहीकृत किया गया है। – DForck42

उत्तर

1

इस क्वेरी की मदद करनी चाहिए

;WITH cte AS 
    (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY FID ORDER BY FID, YearS) AS NUMBER 
    FROM Table2 
    ) 

SELECT t.ID, MAX(CASE WHEN cte.number = 1 THEN cte.YearS END) as yr1, MAX(CASE WHEN cte.number = 1 THEN cte.Val END) as val1, 
MAX(CASE WHEN cte.number = 2 THEN cte.YearS END) as yr2, MAX(CASE WHEN cte.number = 2 THEN cte.Val END) as val2, 
MAX(CASE WHEN cte.number = 3 THEN cte.YearS END) as yr3, MAX(CASE WHEN cte.number = 3 THEN cte.Val END) as val3, 
MAX(CASE WHEN cte.number = 4 THEN cte.YearS END) as yr4, MAX(CASE WHEN cte.number = 4 THEN cte.Val END) as val4 
FROM Table1 T 
JOIN cte ON t.ID = cte.FID 
GROUP BY t.ID 
+0

हाँ, लेकिन मुझे यकीन नहीं है कि कितने साल होंगे, मेरे कॉलम yr4 से आगे बढ़ सकते हैं जैसे yr5, yr6, yr7 –

+0

पंक्तियों के विपरीत, आपके पास चयन खंड में परिभाषित संख्या में कॉलम होना चाहिए (मैं उल्लेख नहीं करूँगा गतिशील एसक्यूएल यहाँ)।आप इस क्वेरी में अधिक कॉलम जोड़ सकते हैं, जो वर्षों के अस्तित्व में होने पर सभी नल मानों का उत्पादन करेगा। – bobs

5

मैं "तालिका 2" नामक एक मेज, डेटा आप अपनी तालिका 2 शीर्षक के अंतर्गत ऊपर से पता चला है युक्त बनाया है।

ID Yr1  Val1 Yr2  Val2 Yr3  Val3 Yr4  Val4 
--------------------------------------------------------------------- 
1 2008 Up 2009 Down 2010 Up 0  
2 2000 Up 2001 Down 2002 Up 2003 Up 
3 2009 Down 2010 Up  0    0  

कारण आप NULL मान नहीं दिख रहा है की वजह से ELSE है:

यहाँ एसक्यूएल मैं एसक्यूएल सर्वर में इस्तेमाल 2008.

WITH RankedValues AS 
(
    SELECT 
     FID AS ID, 
     YearS, 
     ROW_NUMBER() OVER(PARTITION BY FID ORDER BY YearS) AS YearSRank, 
     Val 
    FROM 
     Table2 
) 
SELECT 
    ID, 
    MAX((CASE WHEN YearSRank = 1 THEN YearS ELSE 0 END)) AS Yr1, 
    MAX((CASE WHEN YearSRank = 1 THEN Val ELSE '' END)) AS Val1, 
    MAX((CASE WHEN YearSRank = 2 THEN YearS ELSE 0 END)) AS Yr2, 
    MAX((CASE WHEN YearSRank = 2 THEN Val ELSE '' END)) AS Val2, 
    MAX((CASE WHEN YearSRank = 3 THEN YearS ELSE 0 END)) AS Yr3, 
    MAX((CASE WHEN YearSRank = 3 THEN Val ELSE '' END)) AS Val3, 
    MAX((CASE WHEN YearSRank = 4 THEN YearS ELSE 0 END)) AS Yr4, 
    MAX((CASE WHEN YearSRank = 4 THEN Val ELSE '' END)) AS Val4 
FROM 
    RankedValues 
GROUP BY 
    ID 

एसक्यूएल ऊपर इस का परिणाम देगा है प्रत्येक CASE कथन में। यदि आपके पास NULL मान हैं, तो आवश्यकतानुसार ELSE 0 और ELSE '' हटाएं।

मुझे इस समय सामान्य नहीं है, अगर इस सामान्य को बनाना संभव है, उदाहरण के लिए: अज्ञात मात्रा में अलग-अलग एफआईडी की प्रक्रिया करें, क्योंकि इसका मतलब कॉलम नाम (Yr1, al1, Yr2, आदि ..) उत्पन्न करना भी होगा। सामान्य रूप से।

आप इसे गतिशील एसक्यूएल के साथ संभवतः प्राप्त कर सकते हैं लेकिन जैसा कि मैं गतिशील एसक्यूएल का बड़ा प्रशंसक नहीं हूं, मैं कोशिश करता हूं और उससे निपटने का एक और तरीका देखता हूं।

- संपादित करें (completness के लिए जोड़ा गया धुरी दृष्टिकोण) -

मैं लिंक जो Stefanelli पोस्ट को देखा और मैं आपकी आवश्यकता के लिए नीचे दिए गए एसक्यूएल गयी। हालांकि मुझे गतिशील एसक्यूएल के विचार पसंद नहीं हैं, लेकिन मैं इस विशिष्ट उदाहरण में कोई अन्य रास्ता नहीं ढूंढ पाया।

DECLARE @query VARCHAR(4000) 
DECLARE @years VARCHAR(2000) 

SELECT @years = STUFF((
    SELECT DISTINCT 
     '],[' + ltrim(str(YearS)) 
    FROM Table2 
    ORDER BY '],[' + ltrim(str(YearS)) 
    FOR XML PATH('')), 1, 2, '') + ']' 

SET @query = 
    'SELECT * FROM 
    (
     SELECT FID AS ID,YearS,Val 
     FROM Table2 
    ) AS t 
    PIVOT (MAX(Val) FOR YearS IN (' + @years + ')) AS pvt' 

EXECUTE (@query) 

यह follwing में परिणाम होगा:

ID 2000 2001 2002 2003 2008 2009 2010 
--------------------------------------------------------- 
1 NULL NULL NULL NULL Up  Down Up 
2 Up  Down Up  Up  NULL NULL NULL 
3 NULL NULL NULL NULL NULL Down Up 

निर्भर करता है जो प्रारूप और आपको सबसे ज्यादा पसंद, कम से कम आप अपने विकल्पों बाहर खड़े है दृष्टिकोण।

+0

मैंने अपने काम पर काम करते समय बोब्स जवाब नहीं देखा है। मूल रूप से वही बात। जवाब का डुप्लिकेट करने का मतलब नहीं था। – Nope

संबंधित मुद्दे