2012-10-31 2 views
8

मैं प्रत्येक आईडीएक सबक्वायरी के बिना अधिकतम अनुक्रम के साथ केवल पंक्ति का चयन कैसे करें?

ID | Seq | Age 
------------------- 
A  1  20 
A  2  30 
B  1  25 
B  2  32 
B  3  44 
B  4  48 
C  1  11 

यह

SELECT ID, Age 
FROM Persons a 
WHERE Seq = (SELECT MAX(Seq) FROM Persons b WHERE a.ID = b.ID) 

काम करने के लिए प्रकट होता है लेकिन इस सबसे अच्छा तरीका है, एक ही रास्ता के लिए उच्चतम seq के साथ ही पंक्ति का चयन करने के लिए कोशिश कर रहा हूँ? मुझे उपक्विरी का उपयोग करना पसंद नहीं है अगर मुझे यह नहीं है और मुझे याद है कि आप कुछ उपयोग कर सकते हैं लेकिन मैं भूल जाता हूं कि यह क्या है। कोई उपाय?

+0

आप किस rdbms का उपयोग कर रहे हैं? –

+0

मुख्य रूप से SQL सर्वर, लेकिन यदि यह ऑरैकल संगत है तो यह शानदार है – jenswirf

+0

मेरा 'ROW_NUMBER' दृष्टिकोण ओरेकल में भी काम करता है क्योंकि मैंने एसक्यूएल-फ़िल्ड के साथ परीक्षण किया है। मेरे जवाब में लिंक पर एक नज़र डालें। –

उत्तर

5

मान लिया जाये कि एसक्यूएल-सर्वर (> = 2005) या Oracle (10g?):

WITH CTE AS 
( 
    SELECT 
     ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Seq DESC) AS RN 
     , ID, Age 
    FROM 
     Persons 
) 
SELECT ID, Age 
FROM CTE 
WHERE RN = 1 

ROW_NUMBER एक परिणाम के सेट के एक विभाजन के भीतर एक पंक्ति के अनुक्रमिक संख्या दिखाता है।

संपादित: Oracle में भी काम करता है के रूप में आप देख सकते हैं: http://sqlfiddle.com/#!4/b7e79/2/0

+0

मेरे मस्तिष्क को ताज़ा करने के लिए धन्यवाद, मैंने इसे अतीत में इस्तेमाल किया और अब लंबे समय बाद इसका उपयोग कर रहा है, यह पूरी तरह से काम करता है! – superachu

1

सामान्य तौर पर, आप विंडोइंग या रैंकिंग कार्यों का उपयोग करने के लिए neeed - Rank(), Row_number(), आदि

select * 
from 
(
    select *, row_number() over (partition by id order by age desc) rn 
    from yourtable 
) v 
where rn = 1 

हो जाएगा ताकि SQL सर्वर 2005+ में काम करें - ऑरैकल में आपको *

+0

यह भी सबसे अच्छा तरीका है जिसके बारे में मैंने सोचा होगा। हालांकि, इसमें दो चयन खंड हैं, और यदि आपको यह पसंद नहीं है, तो आप केवल आंतरिक चयन ले सकते हैं और आपके ऐप में जो कुछ भी रैंक नहीं किया गया है उसे देखा गया है;) – OzrenTkalcecKrznaric

1

Jus के बजाय स्पष्ट रूप से फ़ील्ड नाम निर्दिष्ट करने की आवश्यकता हो सकती है टी मामले में आप एक आरडीबीएमएस उस खिड़की कार्यों का समर्थन नहीं करता उपयोग करते हैं, आप का उपयोग कर सकते हैं:

SELECT Persons.ID, Persons.Age, Persons.Seq 
FROM Persons 
     INNER JOIN 
     ( SELECT Persons.ID, MAX(Seq) AS Seq 
      FROM Persons 
      GROUP BY Persons.ID 
     ) MaxP 
      ON MaxP.ID = Persons.ID 
      AND MaxP.Seq = Persons.Seq 

यह अभी भी एक सबक्वेरी शामिल है, लेकिन मैं एक के बिना ऐसा करने का एक तरीका नहीं दिख रहा है, न ही मैं सच में करना समझें कि आप उनसे क्यों बचना चाहते हैं।

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

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