মাইএসকিউএল লাইক ইন ()?


273

আমার বর্তমান ক্যোয়ারীটি এমন দেখাচ্ছে:

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

আমি আশেপাশে কিছু দেখেছি এবং একটি লাইক ইন () এর মতো কিছু খুঁজে পাচ্ছি না - আমি এটি এরকমভাবে কাজ করার কথা ভাবছি:

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

কোন ধারনা? আমি কি সমস্যাটি কেবল ভুল উপায়েই ভাবছি - এমন কিছু অস্পষ্ট আদেশ যা আমি কখনও দেখিনি।

মাইএসকিউএল 5.0.77-সম্প্রদায়-লগ


1
WHERE FIND_IN_SET(f.fiberbox, "1740,1938,1940")
Gjerund Dahl

2
FIND_IN_SET এর মত ওয়াইল্ডকার্ড গ্রহণ করে না%
সেবাস্তিয়ান গ্রিগনোলি

উত্তর:


453

একটি REGEXP বেশি দক্ষ হতে পারে তবে এটি নিশ্চিত হওয়ার জন্য আপনাকে অবশ্যই বেঞ্চমার্ক করতে হবে, যেমন

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

2
আমি এই উত্তরটি পছন্দ করি - দ্রুত, সহজ, আমার পছন্দ মতো (সম্পাদনা করা সহজ) এক লাইনে সমস্ত "বিকল্প" পেয়েছে। ছোট রেজাল্ট সেটটিতে আমি টার্গেট করছি, পারফর্মেন্সে মোটেই হ্রাস পাচ্ছি না।
মাইকেল ওয়েলস 19

51
আমার টেবিলে 1 মিলিয়ন সারি বেশি ows আরেজিএক্স 0.0009 এর কাছাকাছি এবং 0.0005 এর মতো পছন্দ। এরপরে যদি পাঁচটি আরজিইএক্স হয় তবে 0.0012 এর চারপাশে ...
ডেভিড

10
আমার একটি সমস্যা REGEXPছিল যেখানে নিষেধাজ্ঞামূলকভাবে ধীর ছিল, তবে আমার ফলাফলটি LIKEসরবরাহের চেয়ে আরও সংকীর্ণ করার জন্য আরজিইএক্সপি-র নমনীয়তা প্রয়োজন । আমি একটি হাইব্রিড সমাধান নিয়ে এসেছি যেখানে আমি উভয় ব্যবহার করেছি LIKEএবং REGEXP; REGEXPঅংশটি আমাকে সঠিক ফলাফল দেওয়ার জন্য পর্যাপ্ত থাকা সত্ত্বেও, LIKEধীরে ধীরে REGEXPমানদণ্ডটি ব্যবহার করার আগে মাইএসকিউএলকে ফলাফলটি যথেষ্ট পরিমাণে হ্রাস করার অনুমতি দেয় ।
এমপেন

1
একটি কলাম থেকে (select group_concat(myColumn separator '|') from..)
regexp

5
পারফরম্যান্স ডেটা যুক্ত করা হচ্ছে। 229M সারি সহ একটি টেবিলের মাইএসকিএল 5.5-তে, 1 টি পদ অ্যাঙ্করড 3 চর অনুসন্ধান: আরইজিএক্সপি: 16 এস, লাইক: 8.5 এস; 2 পদ: REGEXP: 22.1 এস, লাইক: 9.69; '^ (হিমোগ্লোবিন | হিমাটর? ocrit)। *' বনাম 3 টি পদ যেমন: REGEXP: 36.3, লাইক: 9.59।
জেসি ক্লার্ক

181

পল ডিকসনের উত্তর আমার জন্য উজ্জ্বলভাবে কাজ করেছিল। এটি যুক্ত করতে, এখানে কিছু জিনিস যা আমি রেগেক্সপি ব্যবহার করতে আগ্রহী তাদের জন্য পর্যবেক্ষণ করেছি:

ওয়াইল্ডকার্ড সহ একাধিক লাইক ফিল্টার সম্পন্ন করতে:

 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 উদ্ধৃতিতে এবং | এর মধ্যে মানগুলি (OR) অপারেটরটিকে ওয়াইল্ডকার্ড হিসাবে বিবেচনা করা হয়। সাধারণত, আরজিইএক্সপি-র% 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';
  • মানটির সামনে ^ স্থাপন রেখার সূচনা নির্দেশ করে।

  • মানের পরে $ স্থাপন রেখার শেষ নির্দেশ করে।

  • স্থাপন (। *)%% ওয়াইল্ডকার্ডের মতো আচরণ করে।

  • দ্য . লাইন ব্রেক ব্যতীত যে কোনও একক অক্ষরকে নির্দেশ করে। স্থাপন। ভিতরে () এর সাথে * (। *) একটি পুনরাবৃত্ত প্যাটার্ন যুক্ত করে যা লাইন শেষ অবধি কতগুলি অক্ষর নির্দেশ করে।

নির্দিষ্ট ম্যাচগুলি সঙ্কুচিত করার আরও কার্যকর উপায় রয়েছে তবে এর জন্য নিয়মিত এক্সপ্রেশনগুলির আরও পর্যালোচনা প্রয়োজন। দ্রষ্টব্য: সমস্ত রেইজেক্স নিদর্শনগুলি মাইএসকিউএল স্টেটমেন্টগুলিতে কাজ করে না বলে মনে হয়। আপনাকে আপনার নিদর্শনগুলি পরীক্ষা করতে হবে এবং কী কাজ করে তা দেখতে হবে।

শেষ অবধি, একাধিক লাইক এবং পছন্দ মতো ফিল্টার সম্পন্ন করতে:

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 use ব্যবহার করি। এটি আপনাকে একই অভিব্যক্তিতে ওয়াইল্ডকার্ডের ম্যাচের সাথে নির্দিষ্ট মিলগুলি যুক্ত করতে দেয়। তবে আপনি এই ধরণের বিবৃতি মিশ্রন করতে পারেন যেমন আপনি তালিকাভুক্ত দ্বিতীয় উদাহরণে দেখতে পাচ্ছেন।

পারফরম্যান্স সম্পর্কে, আমি একটি বিদ্যমান টেবিলের বিরুদ্ধে কিছু ছোটখাটো পরীক্ষা চালিয়েছি এবং আমার প্রকরণের মধ্যে কোনও পার্থক্য খুঁজে পাইনি। তবে, আমি কল্পনা করি পারফরম্যান্স বড় ডেটাবেস, বৃহত্তর ক্ষেত্র, বৃহত্তর রেকর্ড গণনা এবং আরও জটিল ফিল্টার সহ একটি সমস্যা হতে পারে।

বরাবরের মতো, উপরের যুক্তিটি যেমনটি বোধগম্য হয় তেমন ব্যবহার করুন।

আপনি যদি নিয়মিত এক্সপ্রেশন সম্পর্কে আরও জানতে চান তবে আমি একটি ভাল রেফারেন্স সাইট হিসাবে www.regular-expressions.info কে প্রস্তাব দিই।


মনে রাখবেন যে NULL মান সহ একটি ক্ষেত্রটি REGEXP এর সাথে মেলে না। আপনি এই সমস্যাটি সমাধান করতে IFNULL ব্যবহার করতে পারেন। WHERE IFNULL(field, '') NOT REGEXP '1740 | 1938'

@ ড্যানিমার্কউক্স যদি আমি (। *) ব্যবহার করতে চাই তবে তবে এটি 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

মানগুলির তালিকা সহ রিজেপেক্স উপায় way

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

7

দুঃখিত, LIKE INমাইএসকিএল এর মতো কোনও অপারেশন নেই ।

আপনি যদি যোগ না দিয়ে লাইক অপারেটরটি ব্যবহার করতে চান তবে আপনাকে এটি এইভাবে করতে হবে:

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

আপনি জানেন, মাইএসকিউএল, এফওয়াইআই, এই ক্যোয়ারীটি অনুকূল করবে না।


4

"লেগ ইন ইন" কার্যকারিতাটি ব্যবহার করার জন্য রেজিএক্সপ চেষ্টা করে এমন কাউকে কেবল নোট করুন।

IN আপনাকে করতে দেয়:

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

REGEXP এ এটি কাজ করবে না

REGEXP '
val1$|
val2$|
val3$
'

এটি এক লাইনে থাকতে হবে:

REGEXP 'val1$|val2$|val3$'

3

ফ্লিপ অপারেশন

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

2
যখন আপনার কিছু ক্ষেত্র স্পষ্টভাবে কিছু সমান হবে যেমন। দি গ্র্যাডস্ জন্য একটি enum 'একটি', 'খ', 'গ' কিন্তু না AB, এসি বা বিসি create table x(en enum('a,b,c')));insert into x values('a'),('b') স্বীকারোক্তি শুধুমাত্র A অথবা B oprands আলোকসম্পাতের দ্বারা এই পদ্ধতি করছেন 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%'মিথ্যা বলে।
এডিটিসি

2

এটি সঠিক হবে:

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

2

একটু টিপস:

আমি বৈকল্পিক ব্যবহার করতে পছন্দ RLIKE (ঠিক একই কমান্ড RegExp ) এটিকে আরো প্রাকৃতিক ভাষা মত শোনাচ্ছে, এবং খাটো হিসেবে; ঠিক আছে, মাত্র 1 চর

"আর" উপসর্গটি রেগের জন্য। অবশ্যই, শেষ।


0

নিয়মিত এক্সপ্রেশনগুলির সাহায্যে আপনি কাঙ্ক্ষিত ফলাফল পেতে পারেন ।

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

আমরা উপরের ক্যোয়ারীটি পরীক্ষা করতে পারি দয়া করে এসকিউএল ভাঁড় ক্লিক করুন

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

আমরা উপরের ক্যোয়ারীটি পরীক্ষা করতে পারি দয়া করে এসকিউএল ভাঁড় ক্লিক করুন


1
এটি একটি ভুল নিয়মিত অভিব্যক্তি। [...]একটি অক্ষর সেট , মানে সেটের কোনও অক্ষরই ম্যাচ হিসাবে দেখা যথেষ্ট। সুতরাং কোনো মান সংখ্যায় ' 0, 1, 3, 4, 7, 8, 9বা |নল চরিত্র এই ম্যাচ হবে।
মার্টিজন পিটারস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.