2011-01-23 5 views
8

मेरे पास किसी प्रकार का असंभव अनुरोध है :)।एसक्यूएल - मुझे प्रत्येक प्रकार के लिए केवल 3 हिट दें

मेरे पास एक सारणी है जहां कॉलम में से एक को type नाम दिया गया है। मैं उस कॉलम में प्रत्येक प्रकार के लिए 3 रिकॉर्ड चुनना चाहता हूं। क्या यह संभव है?

ध्यान दें कि मैं MySQL और स्फिंक्स का उपयोग कर रहा हूं।

अद्यतन: तालिका संरचना

id  title  type 
1  AAAA   string1 
2  CCCC   string2 
3  EEEE   string2 
4  DDDD   string2 
5  FFFF   string2 
6  BBBB   string2 
6  BBBB   string2 

मुझे अपने MySQL वापस करना चाहते है (ऊपर प्रत्येक प्रकार शीर्षक द्वारा आदेश दिया के लिए 3 रिकॉर्ड):

id  title  type 
1  AAAA   string1 
6  BBBB   string2 
2  CCCC   string2 
4  DDDD   string2 
+3

पहला, लगभग कुछ भी असंभव नहीं है। दूसरा, क्यों नहीं अपनी टेबल संरचना और आपने अभी तक क्या प्रयास किया है। – ircmaxell

उत्तर

12
select id, title, type 
from (select id, title, type, 
       @num := if(@group = type, @num + 1, 1) as row_number, 
       @group := type as dummy 
     from your_table 
     order by type, title) as x 
where row_number <= 3 

(! Martin Wickman's answer रूप में एक ही साइट पर a different article का उपयोग करता है)

+0

बहुत बहुत अच्छा! – xpepermint

+0
0

बाहर चेक this लेख। यह देखते हुए:

+--------+------------+-------+ 
| type | variety | price | 
+--------+------------+-------+ 
| apple | gala  | 2.79 | 
| apple | fuji  | 0.24 | 
| apple | limbertwig | 2.87 | 
| orange | valencia | 3.59 | 
| orange | navel  | 9.36 | 
| pear | bradford | 6.05 | 
| pear | bartlett | 2.14 | 
| cherry | bing  | 2.55 | 
| cherry | chelan  | 6.33 | 
+--------+------------+-------+ 

क्वेरी:

select type, variety, price 
from fruits 
where (
    select count(*) from fruits as f 
    where f.type = fruits.type and f.price < fruits.price 
) <= 2; 
+0

यह क्वेरी संबंध दिखाएगी, इसलिए यदि 4 फलों की कीमत समान है, तो वे सभी दिखाए जाते हैं (3 की बजाय)। प्रश्न से जुड़ने का कोई प्रयास नहीं किया गया है। – RichardTheKiwi

+0

यदि सेब की छह किस्मों ने समान, सबसे कम कीमत साझा की, तो सभी छः वापस आ जाएंगे। लेकिन ओपी का उदाहरण मैं सोच रहा हूं कि आईडी शायद एक अद्वितीय पहचानकर्ता है (यदि, है, तो दो "6" को जॉइन के परिणाम के रूप में उत्पादित किया जाता है) और आप मूल्य कॉलम के बजाय आईडी कॉलम का उपयोग कर सकते हैं एक गारंटीकृत सही परिणाम। –

2

जब तालिका बड़ी है और संग्रह अधिक अप्रत्याशित है, पंक्ति क्रमांकन काम करने के लिए दुष्प्रभाव चर के लिए आंतरिक क्वेरी में टाइप करके आदेश दिया जाना चाहिए।

select id, title, type 
from (select id, title, type, 
     @r := CASE WHEN @g = type THEN @r+1 ELSE 1 END r, 
     @g := type 
     from tbl 
     order by type, title) as x 
where row_number <= 3 
# order by type, title 

पक्ष चर प्रभावशाली, अगर कोई दो रिकॉर्ड वास्तव में (शीर्षक, प्रकार, आईडी) पर ही कर रहे हैं का उपयोग किए बिना यह करने के लिए एक और तरीका है, नीचे दी गई है। यह केवल मानक एएनएसआई एसक्यूएल 9 2 एसक्यूएल का उपयोग करता है। हालांकि उपरोक्त से धीमा हो सकता है।

select A.id, A.title, A.type 
from tbl A 
left join tbl B on 
    A.title = B.title and 
    (A.type < B.type or 
    (A.type = B.type and A.id < A.id)) 
group by A.id, A.title, A.type 
having count(B.title) <= 2 
+0

द्वारा तय आदेश के लिए +1 मैंने देखा कि इसे पोस्ट करने से पहले ठीक किया गया था। –

2

आप (type, title) पर एक सूचकांक है, और आप type के लिए संभावित मान पता है, मुझे विश्वास है कि गतिशील एसक्यूएल (एक बार के लिए) सर्वश्रेष्ठ प्रदर्शन के लिए जाने का रास्ता है।

type के प्रत्येक संभावित मूल्य के लिए, सभी को एक यूनियन जोड़ें और उस विशिष्ट प्रकार के लिए चयन करें। ,

(select * from t1 where type = 'string1' order by title limit 3) 
    union all 
(select * from t1 where type = 'string2' order by title limit 3) 
    union all 
(select * from t1 where type = 'string3' order by title limit 3); 

यह 1,000,000 पंक्तियों के साथ एक मेज पर 1 सेकंड से कम में कार्यान्वित दूसरों समाधान (मार्टिंस & Cyberkiwis) लगभग 11 सेकंड लेता है, जबकि: अंतिम क्वेरी निम्न क्वेरी की तरह दिखाई देगा।

अंतर नकली एनालिटिक्स समारोह पूरे तालिका स्कैन करने के लिए है, जबकि क्योंकि ऊपर unioned क्वेरी प्रत्येक प्रकार के लिए पहले तीन शीर्षक प्रविष्टियों प्राप्त कर सके और उसके बाद बंद करो, है।

+0

मेरे डेटाबेस में 200k रिकॉर्ड हैं और 500 से अधिक प्रकार हैं। आपकी क्या सलाह है? – xpepermint

+0

@xpepermint, मार्टिन समाधान के साथ जाएं। बस पता है कि जब आप रिकॉर्ड जोड़ते हैं तो यह धीमा हो जाएगा। किसी बिंदु पर, यह एक लूप में 500 प्रश्नों को करने के लिए तेज़ी से हो जाएगा। आपके सेटअप के आधार पर यह पहले से ही मामला हो सकता है। आपको खुद को मापना होगा। – Ronnis

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