2009-05-07 13 views
19

मैं अपने डेटाबेस में कॉलम के पहले अक्षरों की एक वर्ण सूची बनाना चाहता हूं। नीचे दिए गए एसक्यूएल जो मैं वापस करना चाहता हूं।DISTINCT को एक फ़ील्ड (MySQL) के पहले वर्ण को लौटाना

 
SELECT DISTINCT first_character(name) FROM mydatabase 

क्या MySQL में ऐसा करने का कोई तरीका है?

संपादित करें LEFT पर सबस्ट्रिंग का उपयोग करने का लाभ क्या है और इसके विपरीत?

EDIT वर्तमान में तालिका में लगभग 1700 रिकॉर्ड हैं और बढ़ रहे हैं।

+1

आपकी तालिका में आपके कितने रिकॉर्ड हैं?मैं एक अनुकूलित संस्करण पोस्ट करना चाहता था लेकिन मुझे नहीं पता कि परेशान करना है :) – Quassnoi

+0

ठीक है, मैंने इसे पोस्ट किया है :) शायद कल मैं अपने ब्लॉग में आपके प्रश्न से एक पोस्ट कर दूंगा। – Quassnoi

उत्तर

55

क्षमा करें यह करने के लिए है, लेकिन मैं पता लगा कि वास्तव में क्या मैं सिर्फ अब क्या करने की जरूरत है।

 
SELECT DISTINCT LEFT(name, 1) FROM mydatabase 

यह कॉलम में प्रत्येक पंक्ति के साथ शुरू होने वाले पहले, विशिष्ट, एकल वर्णों की एक सूची लौटा दी। एक आकर्षण की तरह

 
SELECT DISTINCT LEFT(name, 1) as letter FROM mydatabase ORDER BY letter 

काम करता है: मैं निम्नलिखित करने के लिए इसे बदल जोड़ा यह अल्फा-न्यूमेरिक क्रम में सूची प्राप्त करने के।

+0

अपने खुद के सवालों के जवाब पोस्ट करने के लिए यह पूरी तरह से स्वीकार्य है। +1 –

+0

मैं 'SUBSTRING()' का उपयोग करता हूं क्योंकि यह एक SQL मानक है। मुझे 'LEFT()' फ़ंक्शन के लिए मानक नहीं मिला है। http://troels.arvin.dk/db/rdbms/#functions-SUBSTRING – Sonny

9

सरल लगता है:

select distinct substring(field,1,1) as char 
from mytable 
+1

एसक्यूएल मानक उपयोग: 'सब्सट्रेशन (प्रारंभ स्थिति से इनपुट [लंबाई के लिए])' -> 'सब्सट्रिंग (1 से 1 के लिए फ़ील्ड) ' – Sonny

+0

@ सोनी: कीवर्ड' FROM 'के पास गलत वाक्यविन्यास। – Andomar

+0

मुझे यकीन नहीं है कि आप "गलत वाक्यविन्यास" क्यों कहते हैं, मैंने पोस्ट किया गया वाक्यविन्यास यहां दिखाया गया है: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring - पूर्ण क्वेरी यह होगा: 'डिस्टेंस्ट सब्सक्राइजिंग (1 से 1 से फ़ील्ड) के रूप में मेरा टेक्स्ट ' – Sonny

9

1,700 पंक्तियों की आपकी वर्तमान तालिका के लिए आपका समाधान ठीक है।

यदि आपको पंक्तियों के 100,000 पसंद आएंगे, तो DISTINCT अक्षम हो सकता है।

यह समाधान name पर एक सूचकांक को रोजगार:

यहाँ अपने ब्लॉग में लेख से पता चलता है कि कैसे कुशलतापूर्वक यह करने के लिए है। यह इंडेक्स कुंजी पर कूद जाएगा, प्रत्येक बार सबसे पहले अक्षर का चयन करेगा।

सबसे पहले, आप एक समारोह बनाने की आवश्यकता होगी:

CREATE FUNCTION fn_get_next_code(initial INT) RETURNS INT 
NOT DETERMINISTIC 
READS SQL DATA 
BEGIN 
     DECLARE _next VARCHAR(200); 
     DECLARE EXIT HANDLER FOR NOT FOUND RETURN NULL; 
     SELECT ORD(SUBSTRING(name, 1, 1)) 
     INTO _next 
     FROM t_names 
     WHERE name >= CHAR(initial + 1) 
     ORDER BY 
       name 
     LIMIT 1; 
     RETURN _next; 
END 

इस समारोह, एक शुरू करने पत्र की एक कोड दिया, पहले प्रारंभिक पत्र अपनी मेज से दिया करने के लिए अगले देता है।

दूसरा, एक प्रश्न में इस समारोह का उपयोग करें: प्रत्येक यात्रा पर

SELECT CHAR(@r) AS starting, 
     @r := fn_get_next_letter(@r) AS next 
FROM (
     SELECT @r := ORD(LEFT(MIN(name), 1)) 
     ) vars, mytable 
WHERE @r IS NOT NULL 

, सत्र चर @r एक सूचकांक का उपयोग कर अगले प्रारंभिक पत्र के लिए छोड़ देगा।

यह बहुत तेज़ होगा, लेकिन यह केवल तभी भुगतान करता है जब आपके पास सैकड़ों हजार पंक्तियां हों।

अन्यथा बस DISTINCT का उपयोग करें।

+0

+1, जब मुझे ब्रह्मांड में सभी नामित इकाइयों की संयुक्त राष्ट्र तालिका से पूछताछ के लिए बुकमार्क किया गया है: डी – Andomar

+0

सुनिश्चित करें कि यह यूएस ASCII में है, यूनिकोड पर परीक्षण नहीं किया :) – Quassnoi

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