2009-12-10 5 views
11

मैं इस SQL ​​क्वेरी मिल गया है:मैं SQL क्वेरी में प्रति समूह की पहली पंक्ति का चयन कैसे करूं?

SELECT Foo, Bar, SUM(Values) AS Sum 
FROM  SomeTable 
GROUP BY Foo, Bar 
ORDER BY Foo DESC, Sum DESC 

यह इस के समान एक आउटपुट में परिणाम:

47 1 100 
47 0 10 
47 2 10 
46 0 100 
46 1 10 
46 2 10 
44 0 2 

मैं फू प्रति केवल पहली पंक्ति है और बाकी ध्यान नहीं देना चाहते।

47 1 100 
46 0 100 
44 0 2 

मैं यह कैसे कर सकता हूं?

+0

अच्छी तरह से, क्या डेटाबेस और का कौन सा संस्करण क्या आप डीबी का उपयोग कर रहे हैं? टैग के लिए यह एक अच्छा उम्मीदवार है! –

+0

कौन से रिकॉर्ड रखने और किसके लिए त्यागना है, यह चुनने के लिए मानदंड क्या है? – nickf

+0

@ILMV: कभी-कभी मैं चाहता हूं कि आप अच्छे संपादन के लिए प्रतिनिधि अंक दे सकें ... – nickf

उत्तर

22
declare @sometable table (foo int, bar int, value int) 

insert into @sometable values (47, 1, 100) 
insert into @sometable values (47, 0, 10) 
insert into @sometable values (47, 2, 10) 
insert into @sometable values (46, 0, 100) 
insert into @sometable values (46, 1, 10) 
insert into @sometable values (46, 2, 10) 
insert into @sometable values (44, 0, 2) 

;WITH cte AS 
(
    SELECT Foo, Bar, SUM(value) AS SumValue, ROW_NUMBER() OVER(PARTITION BY Foo ORDER BY FOO DESC, SUM(value) DESC) AS RowNumber 
    FROM  @SomeTable 
    GROUP BY Foo, Bar 
) 
SELECT * 
FROM cte 
WHERE RowNumber = 1 
1

बस Players.Nick पर समूह अकेले, और विवरण

SELECT  Players.Nick, MIN(Reasons.Description), SUM(Marks.Value) AS Sum 
FROM   Marks INNER JOIN 
         Players ON Marks.PlayerID = Players.ID INNER JOIN 
         Reasons ON Marks.ReasonId = Reasons.ID 
GROUP BY Players.Nick 
ORDER BY Players.Nick, Sum DESC 

है कि आप हमेशा जानते हुए भी यह

+0

मैं पंक्ति को तीसरे कॉलम में उच्चतम मान के साथ चाहता हूं। – mafu

0

(संपादित प्रश्न के आधार पर संपादित बिना पहली चाहते हैं के पहले (न्यूनतम) का चयन) फिर, चूंकि आप एक समेकित कॉलम के मूल्य के आधार पर फ़िल्टर करना चाहते हैं, तो आपको जो चाहिए वह एक क्लॉज है।

SELECT p.Nick, r.Description, SUM(m.Value) Sum 
    FROM Marks m 
    JOIN Players p 
     ON m.PlayerID = p.ID 
    JOIN Reasons r 
     ON m.ReasonId = r.ID 
    GROUP BY p.Nick, r.Description 
    Having SUM(m.Value) = 
     (Select Max(Sum) From 
     (SELECT SUM(m.Value) Sum 
     FROM Marks mi 
      JOIN Players pi 
       ON mi.PlayerID = pi.ID 
      JOIN Reasons r i 
      ON mi.ReasonId = ri.ID 
     Where pi.Nick = p.Nick 
     GROUP BY pi.Nick, ri.Description)) 

    Order By p.Nick, Sum Desc 
+0

मैं 'एक्स' द्वारा आउटपुट का चयन नहीं करना चाहता हूं। इसके बजाय, तीसरी पंक्ति में मान द्वारा (संपादन देखें)। – mafu

0

सामान्य में, बजाय सबक्वेरी का उपयोग कर में शामिल होने और समूह की कोशिश - यह अक्सर एसक्यूएल है कि बहुत समझने के लिए आसान बनाता है।

SELECT Nick, 
    (SELECT Description from Reasons WHERE Reasons.ID = (
     SELECT FIRST(Marks.ReasonId) from Marks WHERE Marks.PlayerID = Players.ID) 
    ), 
    (SELECT SUM(Value) from Marks WHERE Marks.PlayerID = Players.ID) 
0

यह एक 'होने' खंड का उपयोग करने का अवसर है? (आप एक समग्र समारोह - 'Sum' पर भेदभाव करना चाहते हैं)?

+0

मुझे ऐसा लगता है। यह कैसा दिखेगा? – mafu

2

मैं rjmunru से असहमत हो सकता हूं कि Ansii शैली में शामिल होने से अक्सर सबक्वायरीज़ से पढ़ने के लिए आसान हो सकता है लेकिन प्रत्येक के लिए - मैं बस हमारे डीबीए क्या करना चाहता हूं उसका पालन करता हूं।

यदि आप सिर्फ एक प्रश्न से पहला परिणाम चाहते हैं, तो आप एक राउनम का उपयोग करने में सक्षम हो सकते हैं (यदि ऑरैकल का उपयोग करते हैं, तो अन्य डेटाबेस शायद कुछ समान हैं)।

चयन * च foo_t से जहां f.bar = 'bleh' और ROWNUM = 1

पाठ्यक्रम एक HAVING क्लॉज़ भी उपयुक्त हो सकता है, आपको बस इतना करना कोशिश कर रहे हैं पर निर्भर करता है के

"हैविंग का उपयोग मूल एसक्यूएल स्टेटमेंट में पंक्तियों पर WHERE क्लॉज के समान ग्रुप बी द्वारा बनाए गए समूहों पर कार्रवाई करने के लिए किया जाता है। WHERE क्लॉज मूल्यांकन पंक्तियों को सीमित करता है। हैविंग क्लॉज समूहबद्ध पंक्तियों को वापस कर देता है। "

एचएच

+0

अगर मैं इसे सही ढंग से समझता हूं, तो यह वही है जो मैं चाहता हूं। – mafu

0

उत्सुक। काम करने के लिए मैं इसे प्राप्त करने का एकमात्र तरीका स्मृति में अस्थायी होल्डिंग टेबल का उपयोग कर रहा था। (TSQL वाक्य रचना)

-- original test data 
declare @sometable table (foo int, bar int, value int) 

insert into @sometable values (1, 5, 10) 
insert into @sometable values (1, 4, 20) 
insert into @sometable values (2, 1, 1) 
insert into @sometable values (2, 1, 10) 
insert into @sometable values (2, 1, 1) 
insert into @sometable values (2, 2, 13) 
insert into @sometable values (3, 4, 25) 
insert into @sometable values (3, 5, 1) 
insert into @sometable values (3, 1, 1) 
insert into @sometable values (3, 1, 1) 
insert into @sometable values (3, 1, 1) 
insert into @sometable values (3, 1, 1) 
insert into @sometable values (3, 1, 1) 

-- temp table for initial aggregation 
declare @t2 table (foo int, bar int, sums int) 
insert into @t2 
select foo, bar, sum(value) 
from @sometable 
group by foo, bar 

-- final result 
select foo, bar, sums 
from @t2 a 
where sums = 
    (select max(sums) from @t2 b 
    where b.foo = a.foo) 
0

SQL सर्वर 2005 आप इस का उपयोग कर सकते हैं:

@sometable तालिका (foo पूर्णांक, बार पूर्णांक, मूल्य पूर्णांक) @sometable मूल्यों में

डालने (1 घोषित, 5, 10) @sometable मानों (1, 4, 20) में डालें @sometable मानों (2, 1, 1) @sometable मानों (2, 1, 10) में डालें @sometable मानों में डालें (2, 1, 1) @sometable मानों में डालें (2, 2, 13) @sometable मानों (3, 4, 25) में डालें @sometable मानों (3, 5, 1) @sometable मानों (3, 1, 1) में डालें @sometable मानों में डालें (3, 1, 1) @sometable मूल्यों (3 में डालने, 1, 1) @sometable मूल्यों (3 में डालने, 1, 1) @sometable मूल्यों (3 में डालने, 1, 1)

- अस्थायी तालिका के लिए प्रारंभिक एकत्रीकरण घोषित @ t2 तालिका (foo पूर्णांक, बार पूर्णांक, रकम पूर्णांक) @sometable समूह से @ t2 चयन foo, बार, योग (मान) foo द्वारा में डालने, बार

चयन * से ( चयन foo, बार, रकम, ROW_NUMBER() से अधिक (द्वारा फू आदेश द्वारा सम्स DESC वाला भाग) ROWNO @ t2 से) x जहां x.ROWNO = 1

1

यह एक है पुरानी पोस्ट लेकिन मुझे आज भी यही समस्या थी। मैंने इसे तब तक हल किया है जब तक यह काम नहीं करता है। मैं दृश्य मूल 2010 के साथ एसक्यूएल कॉम्पैक्ट 3.5 का उपयोग कर रहा हूं।

यह उदाहरण कॉलम "आईडी" (प्राथमिक कुंजी), "नाम" (नाम) और "मान" के साथ "टेस्टमैक्स" नाम की एक तालिका के लिए है, जिसका आप उपयोग कर सकते हैं यह प्रत्येक "nom" के लिए अधिकतम "मूल्य" के साथ पंक्तियों प्राप्त करने के लिए:

SELECT TESTMAX.Id, TESTMAX.NOM, TESTMAX.Value 
FROM  TESTMAX INNER JOIN 
        TESTMAX AS TESTMAX_1 ON TESTMAX.NOM = TESTMAX_1.NOM 
WHERE (TESTMAX.Value IN 
         (SELECT MAX(Value) AS Expr1 
         FROM  TESTMAX AS TESTMAX_2 
         WHERE (NOM = TESTMAX_1.NOM))) 
GROUP BY TESTMAX.Id, TESTMAX.NOM, TESTMAX.Value 

आप अन्य पंक्तियां हटाना चाहते हैं, तो आप भी उपयोग कर सकते हैं:

DELETE FROM TESTMAX 
WHERE (Id NOT IN 
         (SELECT TESTMAX_3.Id 
         FROM  TESTMAX AS TESTMAX_3 INNER JOIN 
             TESTMAX AS TESTMAX_1 ON TESTMAX_3.NOM = TESTMAX_1.NOM 
         WHERE (TESTMAX_3.Value IN 
              (SELECT MAX(Value) AS Expr1 
               FROM  TESTMAX AS TESTMAX_2 
               WHERE (NOM = TESTMAX_1.NOM))) 
         GROUP BY TESTMAX_3.Id, TESTMAX_3.NOM, TESTMAX_3.Value)) 
संबंधित मुद्दे