2012-12-21 10 views
5

यहां परिदृश्य है। REGEXP का उपयोग IN ऑपरेटर को अभी तक पर अनुकरण करने के लिए कैसे करें, दोनों तरफ स्ट्रिंग ऑर्डर के बावजूद दायीं तरफ दाएं तरफ सभी मानों से मेल करें। बाएं शामिल होने और उप प्रश्नों का उपयोग करके ANSI SQL समाधान भी हासिल किया जा सकता है।आदेश के बावजूद किसी अन्य समूह सूची में किसी समूह स्ट्रिंग से मिलान करने के लिए REGEXP - SQL

नमूना तालिका:

Parent table, Child table, Parent_Child। प्रश्न पर अधिक जगह न लेने के लिए, मैं केवल Group_Concat Child query by Parent का पुन: प्रस्तुत करता हूं।

PID  NAME  CHILDREN  
1  dad john dave,jill,lina 
2  mum sandy maryam,jack 
3  dad frank henry,jill 
4  mum kate maryam 
5  mum jean dave 

अपेक्षित परिणाम: जनक का चयन करें जो अपने सभी बच्चों को है कुछ में भाग लिया।

PID  NAME  CHILDRENREXGEX 
3  dad frank jill,henry 
4  mum kate maryam 
5  mum jean dave 

यहाँ regexp एसक्यूएल समाधान है: अब यहां मुद्दा यह है, यह सही परिणाम वापस नहीं करता है, तो बाईं ओर आदेश/squence दाईं ओर से मेल नहीं।

क्वेरी:

  1. क्या सबसे अच्छा पैटर्न सही के उपयोगकर्ता परिभाषित सूची में बाईं ओर में सभी के नाम से मेल करने के लिए है:

    select 
        x.pid, x.name, x.children as childrenRexgex 
    from 
        (select 
         p.pid, p.name, group_concat(c.name) as children 
        from 
         parent as p 
        inner join 
         parent_child as pc on p.pid = pc.pid 
        join 
         child as c on pc.cid = c.cid 
        group by 
         p.pid 
        order by 
         c.name) as x 
    where 
        'dave,maryam,jill,henry' REGEXP x.children 
    ; 
    

    इसलिए दो पहलुओं मैं प्रश्न के लिए सराहना करेंगे रहे हैं आदेश के बावजूद पक्ष?

  2. REGEXP का उपयोग करके प्राप्त किया गया प्रदर्शन क्या हो सकता है?
+0

वास्तविक समस्या यह है कि बच्चों को अल्पविराम से अलग कॉलम नहीं होना चाहिए, लेकिन एक विस्तार तालिका होना चाहिए। यह प्रश्न देखें: [क्या डेटाबेस कॉलम में एक सीमित सूची को वास्तव में खराब करना है?] (Http://stackoverflow.com/questions/3653462/is-storing-a-delimited-list-in-a-डेटा-column- वास्तव में-वह-खराब) –

उत्तर

2

क्या आप regexp का उपयोग करना चाहते हैं, या फिर कोई अन्य समाधान ठीक है?

select p.pid, parent.name, group_concat(child.name) 
from 
    (select pid 
    from 
    parent_child inner join child 
    on parent_child.cid = child.cid 
    group by pid 
    having sum(child.name in ('dave','henry','maryam','jill'))=count(*)) p 
    inner join parent on p.pid=parent.pid 
    inner join parent_child on p.pid=parent_child.pid 
    inner join child on parent_child.cid=child.cid 
group by p.pid 

कि देता है:: अगर मैं सही ढंग से समझ, इस क्वेरी आप सही परिणाम देना चाहिए

PID  NAME  CHILDRENREXGEX 
3  dad frank jill,henry 
4  mum kate maryam 
5  mum jean dave 

वैसे भी, अपने समाधान का उपयोग करने, मैं एक आदेश के साथ group_concat उपयोग करने के लिए आपको सुझाव है:

select 
    x.pid, 
    x.name, 
    x.children as childrenRexgex 
from(
    select 
    p.pid, 
    p.name, 
    group_concat(c.name order by c.name) as children, 
    count(c.name) as counts 
    from 
    parent as p inner join parent_child as pc 
    on p.pid = pc.pid 
    join child as c 
    on pc.cid = c.cid 
    group by p.pid) as x 
where 'dave,henry,jill,maryam' 
    REGEXP x.children 

और पहले से ही दिए गए नामों से मेल खाने का प्रयास करें। यह आपकी क्वेरी के समान है, मैंने केवल group_concat के अंदर order by c.name जोड़ा, और मैंने स्ट्रिंग को उस स्थिति में भी आदेश दिया।

संपादित करें: तुम सच में, एक regexp का उपयोग करने के बाद से नियमित अभिव्यक्ति लिए MySQL समर्थन सीमित है चाहते हैं, मैं तुम्हें LIB_MYSQLUDF_PREG इस्तेमाल करने की कोशिश करने के लिए सुझाव है। यह एक सामान्य समाधान है जो मानक MySQL नियमित अभिव्यक्तियों के साथ काम नहीं करता है।

आप इस तरह एक स्ट्रिंग मिलान करने के लिए की जरूरत है:

One,Two,Three,Four 
साथ

, उदाहरण के लिए, इस:

Two,Four,Three,One 

आप इस तरह एक regexp का उपयोग करना होगा:

"One,Two,Three,Four" REGEXP 
"^(?=.*\bTwo\b)(?=.*\bFour\b)(?=.*\bThree\b)(?=.*\bOne\b)" 

(check this question) और यह वही करता है:

  1. \bTwo\b पूर्ण शब्द दो मैचों में हो सकता है: TwoTwo,,Two,Two,
  2. .* शब्द दो स्ट्रिंग .*\bTwo\b
  3. (?=.*\bTwo\b) मैच पूर्ण शब्द दो, स्ट्रिंग, में कहीं भी लेकिन भूल जाते हैं स्थान में कहीं भी पाया जा सकता है और शुरुआत से अगले शब्द को मच करना शुरू करें
  4. अन्य शब्दों से मेल खाना शुरू करें

अभी भी कुछ याद आ रही है? हां, क्योंकि अगर हमारे पास "One,Two,Three,Four", के लिए कोई मिलान है तो "One,Two,Three,Four,Five" मिलान होगा। हो सकता है कि इसके लिए एक बेहतर regexp है, लेकिन मेरा विचार है: यदि वे मेल खाते हैं, और एक ही लंबाई है, तो उन्हें आदेश को छोड़कर समान होना चाहिए। इसलिए हम अपने regexp के अंत में इस जोड़ सकते हैं:

  1. .{length}$ याद रखें कि पहले के सभी मिलान के बाद, हम शुरुआत में अभी भी कर रहे हैं, और ^.{length}$ दिया लंबाई
  2. के एक स्ट्रिंग से मेल खाता

तो अंतिम कोड होगा:

field1="One,Two,Three,Four" 
field2="Two,Four,Three,One" 

field1 REGEXP CONCAT("^(?=.*\b", 
        REPLACE(field2, ",", "\b)(?=.*\b"), 
        "\b).{", LENGTH(field1), "}$") 

सूचना है कि इस regexp regexp द्वारा समर्थित नहीं है, यह LIB_MYSQLUDF_PREG पर समर्थन किया जाना चाहिए लेकिन मैं अभी भी यह परीक्षण नहीं किया। मैं आपको बताउंगा। अन्य समाधान हो सकते हैं, लेकिन मुझे नहीं लगता कि केवल REGEXP के साथ बेहतर प्रदर्शन करना संभव है।

+0

प्रयास के लिए धन्यवाद। मेरे पास पहले से दो प्रश्न हैं जो मुझे 'regexp' के बिना उत्तर देता है। वास्तव में आपकी पहली क्वेरी के समान ही है। इसलिए मुख्य कारण है कि मैं जवाब प्राप्त करने के लिए प्रश्न पोस्ट करता हूं, 'regexp' :-) के आधार पर समाधान शायद मुझे अपने प्रश्न पर और अधिक तनाव की आवश्यकता है। मैं दो अलग-अलग तरीकों के बीच प्रदर्शन को जानना अधिक उत्सुक हूं। – bonCodigo

+0

@bonCodigo मुझे यकीन नहीं था कि आपको इसकी आवश्यकता थी ... केवल regexp का उपयोग करने का विचार अच्छा है .. मेरे पास अभी तक कोई जवाब नहीं है, लेकिन मैं इसके बारे में सोचूंगा :) प्रश्न के लिए +1 – fthiella

+0

बहुत 'regexp' समाधान की ओर किसी भी प्रभावी जानकारी की सराहना की :) मैं वास्तव में पिछली पोस्टों में से एक को चेक कर चुका हूं जहां आपने उत्तर दिया था। [संदर्भ] (http: // stackoverflow।कॉम/प्रश्न/10480568/अल्पविराम से अलग-मूल्य-इन-mysql-in-clause/13445491 # 13445491) – bonCodigo

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