2012-07-27 13 views
9

मेरे तालिका titles ग्रुप तिथि के अनुसार छँटाई इसMySQL द्वारा

id |group|date    |title 
---+-----+--------------------+-------- 
1 |1 |2012-07-26 18:59:30 | Title 1 
2 |1 |2012-07-26 19:01:20 | Title 2 
3 |2 |2012-07-26 19:18:15 | Title 3 
4 |2 |2012-07-26 20:09:28 | Title 4 
5 |2 |2012-07-26 23:59:52 | Title 5 

मैं प्रत्येक समूह के अवरोही क्रम में तिथि के अनुसार क्रमबद्ध से नवीनतम परिणाम की जरूरत है की तरह लग रहा है। इस

id |group|date    |title 
---+-----+--------------------+-------- 
5 |2 |2012-07-26 23:59:52 | Title 5 
2 |1 |2012-07-26 19:01:20 | Title 2 

की तरह कुछ मैं

SELECT * 
FROM `titles` 
GROUP BY `group` 
ORDER BY MAX(`date`) DESC 

कोशिश की, लेकिन मैं समूहों से पहले परिणाम geting हूँ। इस

id |group|date    |title 
---+-----+--------------------+-------- 
3 |2 |2012-07-26 18:59:30 | Title 3 
1 |1 |2012-07-26 19:18:15 | Title 1 

जैसा मैंने क्या गलत कर रहा हूँ? क्या यह प्रश्न अधिक जटिल होने जा रहा है यदि मैं बाएं जॉइन का उपयोग करता हूं?

+0

यदि आपको केवल दो कॉलम चाहिए (उदा। आईडी और इसके नवीनतम टाइमस्टैम्प), तो यह काम कर सकता है: http://stackoverflow.com/a/4448536/722036। यह लाखों पंक्तियों के साथ एक विशाल मेज पर उप-प्रश्नों का उपयोग करने से ** तेज ** है। –

उत्तर

8

This page मेरे लिए बहुत उपयोगी था; यह मुझे प्रति समूह अधिकतम/न्यूनतम/कुछ-पंक्ति पंक्तियों को प्राप्त करने के लिए स्वयं-जुड़ने का उपयोग करने का तरीका सिखाता है।

अपनी स्थिति में, यह प्रभाव के लिए लागू किया जा सकता तुम इतनी तरह हैं:

SELECT * FROM 
(SELECT group, MAX(date) AS date FROM titles GROUP BY group) 
AS x JOIN titles USING (group, date); 
0

ठीक है, यदि दिनांक एक समूह में अद्वितीय हैं इस (काम करेगा नहीं तो, आपको पंक्तियों देखेंगे कि समूह में अधिकतम तिथि से मेल खाते हैं)। (इसके अलावा, स्तंभों की बुरी नामकरण, 'समूह', 'तारीख' आप वाक्यविन्यास त्रुटियों और इस तरह के विशेष रूप से 'समूह' दे सकता है)

select t1.* from titles t1, (select group, max(date) date from titles group by group) t2 
where t2.date = t1.date 
and t1.group = t2.group 
order by date desc 
0

एक और दृष्टिकोण एक "नियंत्रण को तोड़ने की पहचान के लिए MySQL उपयोगकर्ता चर का उपयोग करने के लिए है "group मूल्यों में।

आपको एक अतिरिक्त स्तंभ लौटाए जाने के साथ रह सकते हैं, कुछ इस तरह काम करेगा:

SELECT IF(s.group = @prev_group,0,1) AS latest_in_group 
    , s.id 
    , @prev_group := s.group AS `group` 
    , s.date 
    , s.title 
    FROM (SELECT t.id,t.group,t.date,t.title 
      FROM titles t 
     ORDER BY t.group DESC, t.date DESC, t.id DESC 
     ) s 
    JOIN (SELECT @prev_group := NULL) p 
HAVING latest_in_group = 1 
ORDER BY s.group DESC 

क्या यह क्या कर रही है अवरोही क्रम में group द्वारा सभी पंक्तियों आदेश देने और date द्वारा किया जाता है। (यदि हम (group,date,id) पर एक इंडेक्स हैं तो ऑर्डर द्वारा सभी कॉलम पर डीईएससी निर्दिष्ट करें कि MySQL "रिवर्स स्कैन" कर सकता है। id कॉलम को शामिल करने से हमें निर्धारिती (दोहराने योग्य) व्यवहार मिलता है, मामले में नवीनतम date मान के साथ एक से अधिक पंक्तियां हैं।) यह इनलाइन दृश्य s के रूप में उपनाम है।

हम "चाल" का उपयोग group मान की तुलना पिछली पंक्ति से group मान से करना है। जब भी हमारे पास एक अलग मूल्य होता है, हम जानते हैं कि हम एक "नया" समूह शुरू कर रहे हैं, और यह पंक्ति "नवीनतम" पंक्ति है (हमारे पास आईएफ फ़ंक्शन एक 1 है)। अन्यथा (जब समूह मान मेल खाते हैं), यह नवीनतम पंक्ति नहीं है (और हमारे पास आईएफ फ़ंक्शन 0 देता है)।

फिर, हम उन सभी पंक्तियों को फ़िल्टर करते हैं जिनके पास latest_in_group 1 के रूप में सेट नहीं है।

ऐसा नहीं है कि क्वेरी एक दूसरी क्वेरी में लपेटकर (एक इनलाइन दृश्य के रूप में) द्वारा कि अतिरिक्त स्तंभ निकालना संभव है:

SELECT r.id 
    , r.group 
    , r.date 
    , r.title 
    FROM (SELECT IF(s.group = @prev_group,0,1) AS latest_in_group 
       , s.id 
       , @prev_group := s.group AS `group` 
       , s.date 
       , s.title 
      FROM (SELECT t.id,t.group,t.date,t.title 
        FROM titles t 
        ORDER BY t.group DESC, t.date DESC, t.id DESC 
       ) s 
      JOIN (SELECT @prev_group := NULL) p 
     HAVING latest_in_group = 1 
     ) r 
ORDER BY r.group DESC 
0

अपने id क्षेत्र एक स्वत: incrementing क्षेत्र है, और यह है कि कहने के लिए सुरक्षित है, तो

SELECT b.* 
FROM  (SELECT MAX(id) AS maxid FROM titles GROUP BY group) a 
JOIN  titles b ON a.maxid = b.id 
ORDER BY b.date DESC 
0

तालिका से नवीनतम अद्यतन/डाला रिकॉर्ड प्राप्त करने के लिए नीचे दिए गए mysql क्वेरी का उपयोग करें: id क्षेत्र के उच्चतम मूल्य भी किसी भी समूह की date के लिए सबसे अधिक मूल्य है, तो यह एक सरल उपाय है ।

SELECT * FROM 
(
    select * from `titles` order by `date` desc 
) as tmp_table 
group by `group` 
order by `date` desc 
1

मुझे यह विषय Google के माध्यम से मिला, ऐसा लगता है कि मेरे पास एक ही समस्या थी। यहाँ अपने ही समाधान है कि अगर, मेरी तरह, आप सबक्वेरी पसंद नहीं है:

-- Create a temporary table like the output 
CREATE TEMPORARY TABLE titles_tmp LIKE titles; 

-- Add a unique key on where you want to GROUP BY 
ALTER TABLE titles_tmp ADD UNIQUE KEY `group` (`group`); 

-- Read the result into the tmp_table. Duplicates won't be inserted. 
INSERT IGNORE INTO titles_tmp 
    SELECT * 
    FROM `titles` 
    ORDER BY `date` DESC; 

-- Read the temporary table as output 
SELECT * 
    FROM titles_tmp 
    ORDER BY `group`; 

यह एक तरह से बेहतर प्रदर्शन किया है।

-- Create a temporary table like the output 
CREATE TEMPORARY TABLE titles_tmp LIKE titles; 

-- Add a unique key on where you want to GROUP BY 
ALTER TABLE titles_tmp ADD UNIQUE KEY `group` (`group`); 

-- Read the result into the tmp_table, in the natural order. Duplicates will update the temporary table with the freshest information. 
INSERT INTO titles_tmp 
    SELECT * 
    FROM `titles` 

    ON DUPLICATE KEY 
    UPDATE `id` = VALUES(`id`), 
      `date` = VALUES(`date`), 
      `title` = VALUES(`title`); 

-- Read the temporary table as output 
SELECT * 
    FROM titles_tmp 
    ORDER BY `group`; 

परिणाम::

+----+-------+---------------------+---------+ 
| id | group | date    | title | 
+----+-------+---------------------+---------+ 
| 2 |  1 | 2012-07-26 19:01:20 | Title 2 | 
| 5 |  2 | 2012-07-26 23:59:52 | Title 5 | 
+----+-------+---------------------+---------+ 

बड़ी टेबल पर इस विधि में आता है यहाँ कैसे गति को बढ़ाने के लिए अगर date_column auto_increment_one रूप में एक ही क्रम (आप तो बयान एक ORDER BY की जरूरत नहीं है) है है प्रदर्शन के मामले में एक महत्वपूर्ण बिंदु।

0

प्रत्येक समूह

SELECT 
T1.* FROM 
(SELECT 
    MAX(ID) AS maxID 
FROM 
    T2 
GROUP BY Type) AS aux 
    INNER JOIN 
T2 AS T2 ON T1.ID = aux.maxID ; 

कहाँ आईडी अपने ऑटो वेतन वृद्धि क्षेत्र है और प्रकार के रिकॉर्ड के प्रकार है, तो आप द्वारा समूह चाहता था से सबसे हाल ही रिकॉर्ड प्राप्त करने के लिए निम्न क्वेरी का उपयोग करें।

0

MySQL GROUP BY का एक गूंगा विस्तार जो विश्वसनीय नहीं है इसलिए आप इस तरह के परिणाम प्राप्त करना चाहते हैं का उपयोग करता है, तो आप

select id, group, date, title from titles as t where id = 
(select id from titles where group = a.group order by date desc limit 1); 

इस्तेमाल कर सकते हैं इस क्वेरी में, हर बार मेज तो यह प्रत्येक समूह के लिए पूर्ण स्कैन किया जाता है सबसे हाल की तारीख पा सकते हैं। मुझे इसके लिए कोई बेहतर विकल्प नहीं मिला। उम्मीद है कि यह किसी की मदद करेगा।