2012-04-26 21 views
6

मुझे अधिकतम पंक्ति को पकड़ने के लिए कम से कम दो बार एक ही तालिका को खोजे बिना ऐसा करने में कठिनाई हो रही है, और उसके बाद उस पंक्ति के मान को पकड़ें। प्रश्न में तालिका काफी बड़ी है इसलिए यह अस्वीकार्य है।प्रति समूह एक कॉलम के अधिकतम मूल्य के साथ वापसी पंक्ति

SCORES 
ID ROUND SCORE 
1  1  3 
1  2  6 
1  3  2 
2  1  10 
2  2  12 
3  1  6 

मैं स्कोर कि प्रत्येक आईडी सबसे हाल ही में दौर में मिला वापस जाने के लिए की जरूरत है:

यहाँ क्या मेरी मेज की तरह लग रहे हो सकता है। यही है, अधिकतम (गोल) के साथ पंक्ति, लेकिन अधिकतम स्कोर नहीं।

OUTPUT: 
ID ROUND SCORE 
1 3  2 
2 2  12 
3 1  6 

अभी मेरे पास है:

SELECT * FROM 
(SELECT id, round, 
CASE WHEN (MAX(round) OVER (PARTITION BY id)) = round THEN score ELSE NULL END score 
FROM 
SCORES 
where id in (1,2,3) 
) scorevals 
WHERE 
scorevals.round is not null; 

यह काम करता है, लेकिन बहुत अक्षम (मैं मैन्युअल रूप से इन पंक्तियों के सभी बाहर फिल्टर करने के लिए जब मैं सिर्फ में उन पंक्तियों को आकर्षित नहीं करने के लिए सक्षम होना चाहिए है पहली जगह।)

सही मूल्य प्राप्त करने के लिए मैं क्या कर सकता हूं?

उत्तर

4

कुछ यह भी संभव है सबक्वेरी के बिना कर सकता है:

SELECT DISTINCT 
     id 
     ,max(round) OVER (PARTITION BY id) AS round 
     ,first_value(score) OVER (PARTITION BY id ORDER BY round DESC) AS score 
FROM SCORES 
WHERE id IN (1,2,3) 
ORDER BY id; 

रिटर्न आप के लिए वास्तव में क्या कहा है।
महत्वपूर्ण बात यह है कि DISTINCT विंडो फ़ंक्शंस के बाद लागू किया गया है।

SQL Fiddle.

हो सकता है कि तेजी से, क्योंकि यह दो बार एक ही विंडो का उपयोग करता है:

SELECT DISTINCT 
     id 
     ,first_value(round) OVER (PARTITION BY id ORDER BY round DESC) AS round 
     ,first_value(score) OVER (PARTITION BY id ORDER BY round DESC) AS score 
FROM SCORES 
WHERE id IN (1,2,3) 
ORDER BY id; 

अन्यथा एक ही कर रही है।

+0

मुझे यह पसंद है; बहुत साफ। – Jeremy

3

आप विश्लेषणात्मक कार्यों का उपयोग कर सही रास्ते पर हैं।

SELECT * 
    FROM (SELECT a.*, 
       rank() over (partition by id order by round desc) rnk 
      FROM scores 
     WHERE id IN (1,2,3)) 
WHERE rnk = 1 

लेकिन आप शायद rank समारोह के साथ कुछ इस तरह चाहते हैं वहाँ संबंधों (पंक्तियों को है एक ही id और round) आप rank के बजाय row_number विश्लेषणात्मक समारोह का उपयोग कर सकते हो सकता है - कि मनमाने ढंग से होगा rank दोनों के रूप में लौटने की बजाय दो बंधा पंक्तियों में से एक को rnk में से एक चुनें।

आप MAX विश्लेषणात्मक समारोह उपयोग करना चाहता था, तो आप भी तरह

SELECT * 
    FROM (SELECT a.*, 
       MAX(round) OVER (partition by id) max_round 
      FROM scores 
     WHERE id IN (1,2,3)) 
WHERE round = max_round 
0

समस्याओं के इस प्रकार के लिए, मैं max...keep...dense_rank निर्माण का उपयोग करते हैं:

select 
    id, 
    max(round) round, 
    max(score) keep (dense_rank last order by round) score 
from 
    tq84_scores 
group by 
    id; 

sql fiddle