2010-09-30 22 views
11

मेरे पास एक मेडिकल चेकअप के परिणाम और भेजे गए रिपोर्ट की तारीख और परिणाम को बचाने के लिए इस तरह की एक सारणी है। असल में भेजा गया दिनांक क्लिनिक_विसिट दिनांक पर आधारित है। एक ग्राहक एक या अधिक रिपोर्ट हो सकता है (तारीख मई भिन्न होता है)PostgreSQL: एकाधिक पंक्तियों को कैसे गठबंधन करें?

--------------------------------------- 
| client_id | date_sent | result | 
--------------------------------------- 
| 1   | 2001  | A | 
| 1   | 2002  | B | 
| 2   | 2002  | D | 
| 3   | 2001  | A | 
| 3   | 2003  | C | 
| 3   | 2005  | E | 
| 4   | 2002  | D | 
| 4   | 2004  | E | 
| 5   | 2004  | B | 
--------------------------------------- 

मैं ऊपर डेटा से निम्नलिखित रिपोर्ट निकालना चाहते हैं।

--------------------------------------------------- 
| client_id | result1 | result2 | resut3 | 
--------------------------------------------------- 
|  1  | A  | B  |   | 
|  2  | D  |   |   | 
|  3  | A  | C  |  E  | 
|  4  | D  | E  |   | 
|  5  | B  |   |   | 
--------------------------------------------------- 

मैं पोस्टग्रेस्क्ल पर काम कर रहा हूं। "crosstab" फ़ंक्शन यहां काम नहीं करेगा क्योंकि "date_sent" प्रत्येक क्लाइंट के लिए संगत नहीं है।

क्या कोई भी किसी न किसी विचार को बता सकता है कि इसे कैसे पूछना चाहिए?

उत्तर

14

मैं निम्नलिखित दृष्टिकोण का सुझाव:

SELECT client_id, array_agg(result) AS results 
    FROM labresults 
    GROUP BY client_id; 

यह बिल्कुल नहीं एक ही आउटपुट स्वरूप है, लेकिन यह आप वही जानकारी बहुत तेजी से और क्लीनर दे देंगे।

आप अलग-अलग कॉलम में परिणाम चाहते हैं, तो आप हमेशा ऐसा कर सकते हैं:

SELECT client_id, 
     results[1] AS result1, 
     results[2] AS result2, 
     results[3] AS result3 
FROM 
(
    SELECT client_id, array_agg(result) AS results 
     FROM labresults 
     GROUP BY client_id 
) AS r 
ORDER BY client_id; 

हालांकि कि स्पष्ट रूप से संभावित परिणामों की हार्डकोडेड संख्या का परिचय देंगे।

+0

आपका समाधान काम करता है लेकिन मुझे लगता है कि ओपी सवाल के रूप में डेटा को सारणीबद्ध करना चाहता है, ताकि यह आसान हो देखें कि रिक्त प्रविष्टियां कहां हैं (उदाहरण के लिए क्लाइंट 1 का कोई परिणाम नहीं है)। – SabreWolfy

+2

@SabreWolfy: –

+3

अपडेट किया गया यह उत्तर समस्या हल करता है और ओपी द्वारा स्वीकार किया जाना चाहिए। – SabreWolfy

0

जबकि मैं "simulating row_number" के बारे में पढ़ रहा था, मैंने ऐसा करने का एक और तरीका जानने की कोशिश की।

SELECT client_id, 
     MAX(CASE seq WHEN 1 THEN result ELSE '' END) AS result1, 
     MAX(CASE seq WHEN 2 THEN result ELSE '' END) AS result2, 
     MAX(CASE seq WHEN 3 THEN result ELSE '' END) AS result3, 
     MAX(CASE seq WHEN 4 THEN result ELSE '' END) AS result4, 
     MAX(CASE seq WHEN 5 THEN result ELSE '' END) AS result5 
FROM (SELECT p1.client_id, 
       p1.result, 
       (SELECT COUNT(*) 
       FROM labresults p2 
       WHERE p2.client_id = p1.client_id 
       AND p2.result <= p1.result) 
     FROM labresults p1 
) D (client_id, result, seq) 
GROUP BY client_id; 

लेकिन क्वेरी में 10 मिनट (500,000 एमएस ++) लगे। 30,000 रिकॉर्ड के लिए। यह बहुत लंबा है ..

+0

यह देखने के लिए एक्सप्लान विश्लेषण का उपयोग करें कि क्वेरी कैसे निष्पादित की जाती है और किस इंडेक्स का उपयोग किया जाता है। client_id को एक अनुक्रमणिका की आवश्यकता है। –

+0

धन्यवाद फ्रैंक .. मैंने "client_id" को अनुक्रमित किया और अब यह 5000ms से कम में चलता है। – thinzar00

+2

पोस्टग्रेज़ के साथ आपको row_number "अनुकरण" करने की आवश्यकता नहीं है। यह फ़ंक्शन 8.4 के बाद से उपलब्ध है (और यदि आप पहले के संस्करण का उपयोग कर रहे हैं तो मैं जितनी जल्दी हो सके अपग्रेड करने की दृढ़ता से अनुशंसा करता हूं) –

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