2012-02-20 16 views
5

मैं इस तरह की समस्या पर काफी कुछ समाधान देखा है, लेकिन इनमें से कोई भी उचित होने लगते हैं:पंक्तियां चुनें

मैं निम्न तालिका है लेआउट, संलग्नक, जो संस्थाओं के लिए बाध्य कर रहे हैं की एक संस्करण:

TABLE attachments 
+------+--------------+----------+----------------+---------------+ 
| id | entitiy_id | group_id | version_number | filename  | 
+------+--------------+----------+----------------+---------------+ 
| 1 | 1   | 1  | 1    | file1-1.pdf | 
| 2 | 1   | 1  | 2    | file1-2.pdf | 
| 3 | 1   | 2  | 1    | file2-1.pdf | 
| 4 | 2   | 1  | 1    | file1-1.pdf | 
| 5 | 2   | 1  | 2    | file1-2.pdf | 
| 6 | 2   | 3  | 1    | file3-1.pdf | 
+------+--------------+----------+----------------+---------------+ 

आउटपुट होना चाहिए मैक्स संस्करण संख्या, group_id और ENTITY_ID आधार पर वर्गीकृत किया है, मैं केवल एक entity_ids के लिए एक सूची आवश्यकता होगी कि अगर मदद करता है:

+------+--------------+----------+----------------+---------------+ 
| id | entitiy_id | group_id | version_number | filename  | 
+------+--------------+----------+----------------+---------------+ 
| 2 | 1   | 1  | 2    | file1-2.pdf | 
| 3 | 1   | 2  | 1    | file2-1.pdf | 
| 5 | 2   | 1  | 2    | file1-2.pdf | 
| 6 | 2   | 3  | 1    | file3-1.pdf | 
+------+--------------+----------+----------------+---------------+ 

मैं क्या लेकर आए हैं इस आत्म है के साथ एक में शामिल होने:

SELECT * 
FROM `attachments` `attachments` 
     LEFT OUTER JOIN attachments t2 
     ON (attachments.group_id = t2.group_id 
       AND attachments.version_number < t2.version_number) 
WHERE (t2.group_id IS NULL) 
    AND (`t2`.`id` = 1) 
GROUP BY t2.group_id 

लेकिन यह एक ही काम करता है विभिन्न संस्थाओं एक ही समूह संख्या साझा नहीं करते तो। यह दुर्भाग्य से जरूरी है।

दृश्य बनाने के दौरान मैं एक समाधान समाधान में आया, लेकिन यह मेरे वर्तमान सेटअप में समर्थित नहीं है।

किसी भी विचार की अत्यधिक सराहना की जाती है। धन्यवाद!

उत्तर

3

इस प्रयास करें:

select t1.* from attachments t1 
left join attachments t2 
on t1.entity_id = t2.entity_id and t1.group_id = t2.group_id and 
    t1.version_number < t2.version_number 
where t2.version_number is null 
+0

धन्यवाद! यह एक बहुत ही सरल समाधान है। –

+0

मैं कम से कम सुनिश्चित करता हूं कि आपने तालिका प्रदर्शन को बनाए रखने के लिए सुझाई गई कुंजी को जोड़ दिया है, इसलिए entitiy_id, group_id, और version_number। आपके प्रश्न में आपने निर्दिष्ट किया है कि यह एकल इकाई आईडी के लिए था, और यह विकल्प प्रविष्टि को सीमित करने के लिए उपयोग नहीं किए जा रहे entity_id के कारण उच्च तालिका वॉल्यूम्स पर अन्य सुझावों की तुलना में अधिक धीरे-धीरे प्रदर्शन करेगा। गैर-एएनएसआई के लिए –

+0

-1 –

2

यह सब

SELECT attachments.* 
FROM (
    SELECT entitiy_id, group_id, MAX(version_number) AS max_version 
    FROM attachments 
    GROUP BY entitiy_id, group_id 
) AS maxVersions 
INNER JOIN attachments 
ON attachments.entitiy_id = maxVersions.entitiy_id 
AND attachments.group_id = maxVersions.group_id 
AND attachments.version_number = maxVersions.max_version 

का चयन का विस्तार इस बस एक ही entitiy_id बस सबक्वेरी में एक कहां जोड़ने शामिल होगा देखने के लिए के लिए काम करेगा, तो यह

SELECT attachments.* 
FROM (
    SELECT entitiy_id, group_id, MAX(version_number) AS max_version 
    FROM attachments 
    WHERE entitity_id = [[YOUR ENTITIY ID HERE]] 
    GROUP BY entitiy_id, group_id 
) AS maxVersions 
INNER JOIN attachments 
ON attachments.entitiy_id = maxVersions.entitiy_id 
AND attachments.group_id = maxVersions.group_id 
AND attachments.version_number = maxVersions.max_version 

दे अगर आप चाहें तो होगा यह सुनिश्चित करने के लिए कि पंक्तियों की संख्या बढ़ने के साथ ही यह तेजी से चल रहा है, मैं आपको यह सुनिश्चित करने की सलाह दूंगा कि आप पंक्तियों (entitiy_id, group_id, max_version) पंक्तियों के साथ अनुलग्नकों पर एक कुंजी जोड़ते हैं, तो उपकुंजी उस पर भरोसा करने में सक्षम होगी जिससे यह सुनिश्चित हो सके कि यह लॉक नहीं है टेबल ऊपर।

2

इस चाल करना होगा:

select a1.* from attachments a1 
inner join (select entitiy_id, group_id, max(version_number) as version_number 
      from attachments 
      group by entitiy_id, group_id) a2 on a1.entitiy_id = a2.entitiy_id and 
                a1.group_id = a2.group_id and 
                a1.version_number = a2.version_number 
0

तुम भी एक उच्च प्रदर्शन आम तालिका अभिव्यक्ति (CTE) का उपयोग करते हुए इस हल कर सकते हैं।

WITH CTE AS 
(
SELECT entitiy_id, group_id, version_number, filename,  
ROW_NUMBER() OVER (PARTITION BY entitiy_id, group_id ORDER BY version_number DESC) as RowNum 
FROM attachments 
) 
SELECT entitiy_id, group_id, version_number, filename 
FROM CTE 
WHERE RowNum = 1 

या

SELECT T.entitiy_id, T.group_id, T.version_number, T.filename 
FROM (SELECT entitiy_id, group_id, version_number, filename,  
    ROW_NUMBER() OVER (PARTITION BY entitiy_id, group_id ORDER BY version_number DESC) as RowNum 
    FROM attachments 
    ) as T 
WHERE RowNum = 1 
संबंधित मुद्दे