MySQL की तरह ()?


273

मेरी वर्तमान क्वेरी इस तरह दिखती है:

SELECT * FROM fiberbox f WHERE f.fiberBox LIKE '%1740 %' OR f.fiberBox LIKE '%1938 %' OR f.fiberBox LIKE '%1940 %'

मैंने कुछ तलाश किया और LIKE IN () के समान कुछ भी नहीं पा रहा हूँ - मैं इसे इस तरह से काम करने की कल्पना करता हूँ:

SELECT * FROM fiberbox f WHERE f.fiberbox LIKE IN('%140 %', '%1938 %', '%1940 %')

कोई विचार? क्या मैं सिर्फ इस समस्या को गलत तरीके से सोच रहा हूँ - कुछ अस्पष्ट आदेश जो मैंने कभी नहीं देखे हैं।

MySQL 5.0.77-समुदाय-लॉग


1
WHERE FIND_IN_SET(f.fiberbox, "1740,1938,1940")
गजरमुंड दाहाल

2
FIND_IN_SET वाइल्डकार्ड को स्वीकार नहीं करता है जैसे%
सेबेस्टियन ग्रिग्नोली

जवाबों:


453

एक REGEXP अधिक कुशल हो सकता है, लेकिन आपको यह सुनिश्चित करने के लिए बेंचमार्क करना होगा, जैसे

SELECT * from fiberbox where field REGEXP '1740|1938|1940'; 

2
मुझे यह उत्तर पसंद है - त्वरित, सरल, मुझे एक पंक्ति में सभी "विकल्प" मिले जैसे मैं चाहता था (संपादित करने में आसान)। मेरे द्वारा लक्षित छोटे परिणाम सेट पर, प्रदर्शन में कोई कमी नहीं है।
वेल्स में माइकल वेल्स

51
मेरी तालिका में 1 मिलियन से अधिक पंक्तियाँ। REGEX 0.0009 और LIKE arround 0.0005। यदि अधिक है तो 5 REGEX, 0.0012 पर लिखा है ...
डेविड

10
मेरे पास एक ऐसा मुद्दा REGEXPथा जहां निषेधात्मक रूप से धीमा था, लेकिन मुझे अपना परिणाम सेट करने की तुलना में आगे बढ़ने के लिए REGEXP के लचीलेपन की आवश्यकता थी LIKE। मैं एक हाइब्रिड समाधान के साथ आया था जहां मैंने दोनों का उपयोग किया LIKEऔर REGEXP; REGEXPहिस्से के बावजूद मुझे सही परिणाम देने के लिए पर्याप्त है, LIKEसाथ ही साथ स् थाप REGEXPमानदंड का उपयोग करने से पहले MySQL परिणाम सेट को काफी कम करने की अनुमति देता है।
एमपैन

1
एक कॉलम से regexp मान प्राप्त करने के लिए:(select group_concat(myColumn separator '|') from..)
daVe

5
प्रदर्शन डेटा में जोड़ना। 229M पंक्तियों के साथ एक तालिका में MySql 5.5 पर, एक 1 शब्द बचे हुए 3 चार्ट खोज लंगर: REGEXP: 16s, LIKE: 8.5s; 2 शर्तें: REGEXP: 22.1s, LIKE: 9.69; '^ (हीमोग्लोबिन | हेमट्र? ocrit)। *' बनाम 3 शब्द जैसे: REGEXP: 36.3, LIKE: 9.59।
जेसी क्लार्क

181

पॉल डिक्सन के जवाब ने मेरे लिए शानदार काम किया। इसे जोड़ने के लिए, यहां कुछ चीजें दी गई हैं, जिन्हें मैं REGEXP का उपयोग करने में रुचि रखने वालों के लिए देख रहा हूं:

वाइल्डकार्ड के साथ कई तरह के फिल्टर को पूरा करने के लिए:

 SELECT * FROM fiberbox WHERE field LIKE '%1740 %'
                           OR field LIKE '%1938 %'
                           OR field LIKE '%1940 %';  

REGEXP वैकल्पिक का उपयोग करें:

 SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |1940 ';

REGEXP उद्धरण के भीतर और बीच में मान | (या) ऑपरेटर को वाइल्डकार्ड के रूप में माना जाता है। आमतौर पर, REGEXP को वाइल्डकार्ड एक्सप्रेशंस जैसे (। *) 1740 (? *) के लिए% 1740% काम करना होगा।

यदि आपको वाइल्डकार्ड के प्लेसमेंट पर अधिक नियंत्रण की आवश्यकता है, तो इनमें से कुछ प्रकारों का उपयोग करें:

नियंत्रित वाइल्डकार्ड प्लेसमेंट के साथ पसंद को पूरा करने के लिए:

SELECT * FROM fiberbox WHERE field LIKE '1740 %'
                          OR field LIKE '%1938 '
                          OR field LIKE '%1940 % test';  

उपयोग:

SELECT * FROM fiberbox WHERE field REGEXP '^1740 |1938 $|1940 (.*) test';
  • मान के सामने ^ रखने से लाइन की शुरुआत का संकेत मिलता है।

  • मूल्य के बाद $ रखने से लाइन के अंत का संकेत मिलता है।

  • रखने से (। *)% वाइल्डकार्ड की तरह व्यवहार होता है।

  • द। लाइन टूटने को छोड़कर किसी भी एक वर्ण को इंगित करता है। रखने की जगह। अंदर () के साथ * (। *) पंक्ति के अंत तक किसी भी वर्ण का संकेत देने वाला दोहराव पैटर्न जोड़ता है।

विशिष्ट मैचों को कम करने के लिए अधिक कुशल तरीके हैं, लेकिन इसके लिए नियमित अभिव्यक्तियों की अधिक समीक्षा की आवश्यकता है। नोट: सभी regex पैटर्न MySQL स्टेटमेंट में काम नहीं करते हैं। आपको अपने पैटर्न का परीक्षण करना होगा और देखना होगा कि क्या काम करता है।

अंत में, कई तरह की संपत्तियों को पूरा करने के लिए और फिल्टर को पसंद न करें:

SELECT * FROM fiberbox WHERE field LIKE '%1740 %'
                          OR field LIKE '%1938 %'
                          OR field NOT LIKE '%1940 %'
                          OR field NOT LIKE 'test %'
                          OR field = '9999';

REGEXP वैकल्पिक का उपयोग करें:

SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |^9999$'
                          OR field NOT REGEXP '1940 |^test ';

या मिश्रित वैकल्पिक:

SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 '
                          OR field NOT REGEXP '1940 |^test '
                          OR field NOT LIKE 'test %'
                          OR field = '9999';

ध्यान दें मैंने एक अलग WHERE फ़िल्टर में सेट नहीं किया है। मैंने निगेटिव पैटर्न, फॉरवर्ड लुकिंग पैटर्न आदि का प्रयोग किया। हालाँकि, ये भाव वांछित परिणाम नहीं देते थे। ऊपर दिए गए पहले उदाहरण में, मैं सटीक मिलान इंगित करने के लिए ^ 9999 $ का उपयोग करता हूं। यह आपको एक ही अभिव्यक्ति में वाइल्डकार्ड मैचों के साथ विशिष्ट मैच जोड़ने की अनुमति देता है। हालाँकि, आप इस प्रकार के कथनों को भी मिला सकते हैं जैसा कि आप सूचीबद्ध दूसरे उदाहरण में देख सकते हैं।

प्रदर्शन के बारे में, मैंने एक मौजूदा तालिका के खिलाफ कुछ मामूली परीक्षण किए और मेरी विविधताओं के बीच कोई अंतर नहीं पाया। हालाँकि, मुझे लगता है कि प्रदर्शन बड़े डेटाबेस, बड़े क्षेत्र, अधिक से अधिक रिकॉर्ड मायने रखता है, और अधिक जटिल फिल्टर के साथ एक मुद्दा हो सकता है।

हमेशा की तरह, ऊपर तर्क का उपयोग करें क्योंकि यह समझ में आता है।

यदि आप नियमित अभिव्यक्तियों के बारे में अधिक जानना चाहते हैं, तो मैं एक अच्छी संदर्भ साइट के रूप में www. अनियमित-expressions.info की सलाह देता हूं।


ध्यान रखें कि मान NULL वाला एक क्षेत्र REGEXP से मेल नहीं खाएगा। आप इस समस्या को हल करने के लिए IFNULL का उपयोग कर सकते हैं। WHERE IFNULL(field, '') NOT REGEXP '1740 | 1938'

@DanyMarcoux क्या है अगर मैं (? *) का उपयोग करना चाहता हूं, लेकिन इसे FIELDNAME LIKE '%%' की तरह काम करना चाहिए, इसे regexp के साथ कैसे उपयोग किया जाए, ताकि खाली स्ट्रिंग पास हो जाए। यह सभी रिकॉर्ड प्राप्त करना चाहिए ..
shzyincu

हमेशा फ़ील्ड को '% 1940%' या 'फ़ील्ड नहीं पसंद करें' परीक्षण% 'हमेशा सभी पंक्तियों को वापस कर देगा। हो सकता है कि आपके द्वारा बताए गए वांछित परिणामों को अर्जित न करने में योगदान दिया हो?
हर्बर्ट वान-वेलीट

14

आप एक इनलाइन दृश्य या एक अस्थायी तालिका बना सकते हैं, इसे आप मूल्यों से भर सकते हैं और इसे जारी कर सकते हैं:

SELECT  *
FROM    fiberbox f
JOIN    (
        SELECT '%1740%' AS cond
        UNION ALL
        SELECT '%1938%' AS cond
        UNION ALL
        SELECT '%1940%' AS cond
        ) с
ON      f.fiberBox LIKE cond

हालाँकि, यह आपके लिए कई पंक्तियों को लौटा सकता fiberboxहै '1740, 1938', जैसे कि कुछ ऐसा है , जिससे यह क्वेरी आपके लिए बेहतर हो सकती है:

SELECT  *
FROM    fiberbox f
WHERE   EXISTS
        (
        SELECT  1
        FROM    (
                SELECT '%1740%' AS cond
                UNION ALL
                SELECT '%1938%' AS cond
                UNION ALL
                SELECT '%1940%' AS cond
                ) с
        WHERE   f.fiberbox LIKE cond
        )

13

मूल्यों की सूची के साथ Regexp तरीका

SELECT * FROM table WHERE field regexp concat_ws("|",
"111",
"222",
"333");

7

क्षमा करें, LIKE INmysql में इसके समान कोई ऑपरेशन नहीं है ।

यदि आप LIKE ऑपरेटर को बिना ज्वाइन के उपयोग करना चाहते हैं, तो आपको इसे इस तरह करना होगा:

(field LIKE value OR field LIKE value OR field LIKE value)

आप जानते हैं, MySQL उस क्वेरी, FYI का अनुकूलन नहीं करेगा।


4

REGEXP "LIKE IN" कार्यक्षमता का उपयोग करने के लिए किसी को भी ध्यान दें।

IN आपको करने की अनुमति देता है:

field IN (
'val1',
'val2',
'val3'
)

REGEXP में यह काम नहीं करेगा

REGEXP '
val1$|
val2$|
val3$
'

यह इस तरह से एक पंक्ति में होना चाहिए:

REGEXP 'val1$|val2$|val3$'

3

पलटें

'a,b,c' like '%'||field||'%'

2
जब आपके पास कुछ फ़ील्ड है तो स्पष्ट रूप से कुछ समान होगा। grads के लिए एक enum 'एक', 'बी', 'सी' नहीं बल्कि अब, एसी या बीसी create table x(en enum('a,b,c')));insert into x values('a'),('b') एन केवल एक या बी oprands flipping द्वारा इस विधि कर select * from, x where 'a,c' like concat('%',en,'%')में सुरक्षित हो सकते हैं एसक्यूएल निषेधाज्ञा की तरह charactors से बचने के लिए कोई जरूरत नहीं $ ^ आदि

यह समान नहीं है और सामान्य मामलों के लिए काम नहीं करेगा। यदि आप जानते थे कि fieldकेवल ठीक हो सकता है a, bया cफिर आपको उपयोग करना चाहिए field IN ('a', 'b', 'c')। लेकिन सामान्य मामलों में, यह कभी भी प्रतिस्थापित नहीं field LIKE '%a%' OR field LIKE '%b%' OR ...कर सकता क्योंकि फ़ील्ड ही कुछ ऐसा हो सकता है magicजो 'magic' LIKE '%a%'सही लेकिन अभिव्यक्ति को 'a,b,c' LIKE '%magic%'गलत बना देगा।
ADTC

2

यह सही होगा:

SELECT * FROM table WHERE field regexp concat_ws("|",(
"111",
"222",
"333"
));

2

बस थोड़ा सा टिप:

मैं वेरिएंट RLIKE ( REGEXP की तरह ही कमांड ) का उपयोग करना पसंद करता हूं क्योंकि यह प्राकृतिक भाषा की तरह लगता है, और छोटा होता है; ठीक है, सिर्फ 1 चार।

"R" उपसर्ग Reg के लिए है। ऍक्स्प।, बिल्कुल।


0

आप नियमित एक्सप्रेशन की मदद से वांछित परिणाम प्राप्त कर सकते हैं ।

SELECT fiberbox from fiberbox where fiberbox REGEXP '[1740|1938|1940]';

हम उपरोक्त क्वेरी का परीक्षण कर सकते हैं कृपया SQL फिडल पर क्लिक करें

SELECT fiberbox from fiberbox where fiberbox REGEXP '[174019381940]';

हम उपरोक्त क्वेरी का परीक्षण कर सकते हैं कृपया SQL फिडल पर क्लिक करें


1
यह एक गलत नियमित अभिव्यक्ति है। [...]एक वर्ण सेट है , जिसका अर्थ है कि सेट में कोई भी वर्ण एक मैच के रूप में देखने के लिए पर्याप्त है। तो किसी भी मूल्य अंकों के साथ ' 0, 1, 3, 4, 7, 8, 9या |पाइप चरित्र इस से मेल खाएगी।
मार्टिन पीटर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.