2009-05-29 20 views
45

मैं निम्न तालिका है:3 सबसे हाल ही में रिकॉर्ड जहां एक स्तंभ के मूल्यों अलग हैं का चयन करें

id  time  text  otheridentifier 
    ------------------------------------------- 
    1  6   apple  4 
    2  7   orange 4 
    3  8   banana 3 
    4  9   pear  3 
    5  10  grape  2 

क्या मैं 3 सबसे हाल ही में रिकॉर्ड का चयन किया जाता है (समय की वर्णन द्वारा) ऐसा करने के लिए, जिसका otheridentifier चाहते एस अलग हैं। 5, 4, और 2.

id = 3 एक ही otheridentifier क्षेत्र के साथ एक और अधिक हाल के रिकॉर्ड है क्योंकि इस बात को छोड़ दिया जाएगा: इस मामले में तो, परिणाम id की होगी। मैं id = 5 की पंक्तियों हो रही अंत

SELECT * FROM `table` GROUP BY (`otheridentifier`) ORDER BY `time` DESC LIMIT 3 

हालांकि,, , और 1 के बजाय 5, 4, 2 अपेक्षा के अनुरूप:

यहाँ मैं करने की कोशिश की क्या है।

क्या कोई मुझे बता सकता है कि यह प्रश्न मुझे अपेक्षित क्यों नहीं करेगा? मैंने एएससी द्वारा ऑर्डर को बदलने की कोशिश की लेकिन यह आसानी से लौटाई गई पंक्तियों को 1, 3, 5 पर पुनर्व्यवस्थित करता है।

उत्तर

34

यह आपके द्वारा अपेक्षित चीज़ों को वापस नहीं लौटाता है क्योंकि ऑर्डर करने से पहले समूह करना होता है, जैसा कि खंडों की स्थिति से प्रतिबिंबित होता है एसक्यूएल कथन दुर्भाग्य से आप जो पंक्तियां चाहते हैं उन्हें प्राप्त करने के लिए फैनसीयर प्राप्त करना होगा। इस प्रयास करें:

SELECT * 
FROM `table` 
WHERE `id` = (
    SELECT `id` 
    FROM `table` as `alt` 
    WHERE `alt`.`otheridentifier` = `table`.`otheridentifier` 
    ORDER BY `time` DESC 
    LIMIT 1 
) 
ORDER BY `time` DESC 
LIMIT 3 
+1

मैं बार मैं घंटे बिताए इस तरह sql ठीक करने के लिए याद किया और पता चला है mysql 4.0 नेस्टेड प्रश्नों का समर्थन नहीं करता, पी – Unreality

+1

@Unreality: Fortu संक्षेप में उपक्विरी से जुड़े अधिकांश समाधानों को आवश्यक होने पर जुड़ने के रूप में व्यक्त किया जा सकता है। :) – Rytmis

+1

हाँ, लेकिन ORDER/LIMIT वाले लोग _not_ आसानी से जॉइन द्वारा व्यक्त किए गए हैं ... –

2
SELECT * FROM table t1 
WHERE t1.time = 
    (SELECT MAX(time) FROM table t2 
    WHERE t2.otheridentifier = t1.otheridentifier) 
+0

यह प्रति व्यक्ति पहचानकर्ता की नवीनतम पंक्ति का चयन कैसे करेगा? – Andomar

+0

@Andomar: जब मैं पूरी तरह से जाग नहीं रहा हूं तो मुझे सवालों का जवाब देने की कोशिश नहीं करनी चाहिए। कॉलम नामों को थोड़ा सा बदल दिया - देखें कि क्या यह अब और अधिक समझ में आता है। :) – Rytmis

18

आप otheridentifier प्रति अंतिम प्रविष्टि फिल्टर करने के लिए खुद पर तालिका शामिल हो सकते हैं, और फिर उसके ऊपर 3 पंक्तियों ले:

SELECT last.* 
FROM `table` last 
LEFT JOIN `table` prev 
    ON prev.`otheridentifier` = last.`otheridentifier` 
    AND prev.`time` < last.`time` 
WHERE prev.`id` is null 
ORDER BY last.`time` DESC 
LIMIT 3 
+0

एंडोमर, क्या आप समझ सकते हैं कि MySQL आपकी क्वेरी में तालिका 'prev' का उपयोग कैसे कर रहा है? मैंने इसे स्थानीय क्वेरी पर उपयोग करने का प्रयास किया और मुझे 'डेटाबेस.prev' मौजूद नहीं होने में त्रुटि मिल रही है। –

+0

ओपी के डेटा और आपकी क्वेरी के साथ पहेली। निश्चित नहीं है कि यह जवाब 6 बार क्यों बढ़ाया गया था - यह यहां काम नहीं कर रहा है: http://sqlfiddle.com/#!2/ace0b/1 –

+1

@acoder: आप सही हैं, क्वेरी में एक छोटी सी त्रुटि थी: 'बाएं जॉइन' के बाद टेबल नाम गायब था। मैंने जवाब अपडेट कर लिया है। – Andomar

2

Andomar's answer शायद सबसे अच्छा में है कि यह एक subquery का उपयोग नहीं करता है।

एक वैकल्पिक दृष्टिकोण:

select * 
from `table` t1 
where t1.`time` in (
        select max(s2.`time`) 
        from  `table` t2 
        group by t2.otheridentifier 
        ) 
+0

मुझे लगता है कि यदि समय मूल्य अद्वितीय नहीं हैं तो मुझे यहां एक समस्या दिखाई दे रही है - यह पंक्तियों को वापस कर सकती है जो इसे नहीं करना चाहिए। मान लीजिए कि एक समय मूल्य है जो एक अन्य पहचानकर्ता के लिए अधिकतम है, लेकिन कहता है, दूसरा अन्य पहचानकर्ता के लिए दूसरा सबसे बड़ा है। क्या यह प्रश्न तब अन्य अभ्यर्थियों को वापस नहीं करेगा? हालांकि मैं पूरी तरह से बंद हो सकता है, मैं अभी भी थोड़ा थका हुआ हूँ। :) – Rytmis

+0

@Rytmis: हाँ, और मेरी क्वेरी भी होगी, और तुम्हारा :) हेहे – Andomar

+0

@Andomar: हम्म, क्या आप मेरी क्वेरी के बारे में निश्चित हैं? क्योंकि मैंने अभी एक पंक्ति (6, 7, 'स्ट्रॉबेरी', 3) जोड़कर इसका परीक्षण किया है - समय मूल्य 7 समूह में सबसे बड़ा है जिसमें अन्य पहचानकर्ता 4 है, लेकिन दूसरे में दूसरा सबसे बड़ा है। क्वेरी अभी भी ओपी चाहता था पंक्तियों को लौटता है। क्या मेरा टेस्ट केस गलत है? :) – Rytmis

1

क्या

के बारे में
SELECT *, max(time) FROM `table` group by otheridentifier 
+0

संपादित करें - यह ओपी के डेटा पर काम करता है। मेरे पास मेरी क्वेरी में कुछ अतिरिक्त शामिल थे। यह ओपी के डेटा के साथ ठीक काम करता है। http://sqlfiddle.com/#!2/ace0b/2 –

+1

यह अफवाह काम नहीं कर रहा है। अपने sqlfiddle में, यह नारंगी और नाशपाती दिखाना चाहिए - उनका समय मूल्य अधिक है। – mahemoff

+0

@mahemoff यह ठीक से काम नहीं करता जैसा आपने कहा था। – GusDeCooL

4

मैं एक ऐसी ही आवश्यकता थी, लेकिन मैं और अधिक उन्नत चयन मानदंड था। अन्य उत्तर मैं नहीं मिल सका मैं वास्तव में क्या जरूरत से कुछ का उपयोग करना है, लेकिन मैंने पाया आप अभी भी इस तरह के द्वारा के बाद और एक ग्रुप कर सकते हैं:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t 
GROUP BY t.otheridentifier 
+0

मेरे लिए बारीकी से काम करता है !! – wiLLiamcastrO

2

आप सही जवाब पाने के लिए इस क्वेरी का उपयोग कर सकते हैं:

SELECT * FROM 
     (SELECT * FROM `table` order by time DESC) 
      t group by otheridentifier 
0

भी यह:

SELECT * FROM 
OrigTable T INNER JOIN 
( 
SELECT otheridentifier,max(time) AS duration 
FROM T 
GROUP BY otheridentifier) S 
ON S.duration = T.time AND S.otheridentifier = T.otheridentifier. 
संबंधित मुद्दे