SQL में "LIKE" और "IN" का संयोजन है?


340

SQL I (दुख की बात है) में अक्सर LIKEडेटाबेस के कारण " " शर्तों का उपयोग करना पड़ता है जो सामान्यीकरण के लगभग हर नियम का उल्लंघन करते हैं। मैं अभी उसको नहीं बदल सकता। लेकिन यह सवाल अप्रासंगिक है।

इसके अलावा, मैं अक्सर WHERE something in (1,1,2,3,5,8,13,21)अपने एसक्यूएल बयानों की बेहतर पठनीयता और लचीलेपन के लिए स्थितियों का उपयोग करता हूं।

क्या जटिल उप-चयनों को लिखे बिना इन दोनों चीजों को संयोजित करने का कोई संभावित तरीका है?

मैं WHERE something LIKE ('bla%', '%foo%', 'batz%')इसके बजाय कुछ आसान चाहता हूं :

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

मैं यहाँ SQl सर्वर और Oracle के साथ काम कर रहा हूँ, लेकिन मुझे दिलचस्पी है अगर यह किसी भी RDBMS में संभव है।


1
आपको करना है और पसंद करना है या: और (कुछ चीज़ '% चीज़%' या कुछ LIKE '% चीज़%' या कुछ LIKE '% चीज़%')
कॉस्मिक हॉक

काश हमारे पास टेराडाटा का like any/ like all: stackoverflow.com/questions/40475982/sql-like-any-vs-like-all होता । (रिकॉर्ड के लिए, यह ओरेकल कम्यूनिटी आइडियाज़ फोरम समुदाय पर अनुरोध किया गया है
विलियम रॉबर्टसन

जवाबों:


196

SQL में LIKE & IN का संयोजन नहीं है, TSQL (SQL सर्वर) या PLSQL (Oracle) में बहुत कम है। इसका कारण यह है कि पूर्ण पाठ खोज (FTS) अनुशंसित विकल्प है।

Oracle और SQL Server FTS कार्यान्वयन दोनों CONTAINS कीवर्ड का समर्थन करते हैं, लेकिन सिंटैक्स अभी भी थोड़ा अलग है:

आकाशवाणी:

WHERE CONTAINS(t.something, 'bla OR foo OR batz', 1) > 0

एस क्यू एल सर्वर:

WHERE CONTAINS(t.something, '"bla*" OR "foo*" OR "batz*"')

आपके द्वारा क्वेरी किया जा रहा कॉलम पूर्ण-पाठ अनुक्रमित होना चाहिए।

संदर्भ:


11
हाय, ओरेकल के साथ, आपको उन कॉलमों पर प्लेटेक्स्ट इंडेक्स बनाने की आवश्यकता है जिन्हें आप "CONTAINS" ऑपरेटर लागू करना चाहते हैं। आपके डेटा की मात्रा के आधार पर यह काफी लंबा हो सकता है।
पियरे-गाइल्स लेवेलोइस

18
SQL सर्वर के साथ (कम से कम 2008 संस्करण) @Pilooz की टिप्पणी भी लागू होती है, आपको पूर्ण पाठ अनुक्रमणिका बनाने की आवश्यकता है।
मार्सेल

अधिकतम लंबाई 4000 है।
is is

59

यदि आप अपने कथन को आसानी से पढ़ने योग्य बनाना चाहते हैं, तो आप REGEXP_LIKE (Oracle संस्करण 10 से उपलब्ध) का उपयोग कर सकते हैं।

एक उदाहरण तालिका:

SQL> create table mytable (something)
  2  as
  3  select 'blabla' from dual union all
  4  select 'notbla' from dual union all
  5  select 'ofooof' from dual union all
  6  select 'ofofof' from dual union all
  7  select 'batzzz' from dual
  8  /

Table created.

मूल वाक्यविन्यास:

SQL> select something
  2    from mytable
  3   where something like 'bla%'
  4      or something like '%foo%'
  5      or something like 'batz%'
  6  /

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

और REGEXP_LIKE के साथ एक साधारण सी दिखने वाली क्वेरी

SQL> select something
  2    from mytable
  3   where regexp_like (something,'^bla|foo|^batz')
  4  /

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

परंतु ...

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


4
10g में REGEXP उपयोग का +1 अच्छा चित्रण। मैं उत्सुक हूं, हालांकि, अगर प्रदर्शन वास्तव में बहुत बुरा होगा। दोनों को पूर्ण तालिका और / या सूचकांक स्कैन की आवश्यकता होगी, नहीं?
डीसीयूकी

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

49

आप के साथ फंस रहे हैं

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

जब तक आप एक टेम्‍प टेबल (डेटा के साथ वाइल्‍ड कार्ड शामिल करें) को पॉप्युलेट नहीं करते हैं और इस तरह से जुड़ते हैं:

FROM YourTable                y
    INNER JOIN YourTempTable  t On y.something LIKE t.something

इसे आज़माएं (SQL सर्वर सिंटैक्स का उपयोग करके):

declare @x table (x varchar(10))
declare @y table (y varchar(10))

insert @x values ('abcdefg')
insert @x values ('abc')
insert @x values ('mnop')

insert @y values ('%abc%')
insert @y values ('%b%')

select distinct *
FROM @x x
WHERE x.x LIKE '%abc%' 
   or x.x LIKE '%b%'


select distinct x.*  
FROM @x             x
    INNER JOIN  @y  y On x.x LIKE y.y

उत्पादन:

x
----------
abcdefg
abc

(2 row(s) affected)

x
----------
abc
abcdefg

(2 row(s) affected)

ठीक है, यह काम करेगा, लेकिन यह एसक्यूएल स्टेटमेंट को अधिक आसानी से पठनीय बनाने की मेरी इच्छित दिशा में नहीं जा रहा है :)
selfawaresoup

10
SQL में आप इंडेक्स के उपयोग और प्रदर्शन के लिए जाते हैं। एसक्यूएल पठनीयता के लिए केवल इंडेंटिंग और नामकरण का उपयोग करें, जब आप पठनीयता के लिए अन्य संशोधन करते हैं तो आप केवल निष्पादन योजना (जो सूचकांक उपयोग और प्रदर्शन को प्रभावित करता है) को बदलने का जोखिम उठाते हैं। यदि आप सावधान नहीं हैं, तो आप आसानी से तुच्छ परिवर्तन करके तुरंत चलने वाली क्वेरी को बहुत धीमी गति से बदल सकते हैं।
के.एम.

इस उत्तर का पहला कथन कुंजी है - (अधिकांश?) SQL- आधारित सिस्टम और भाषाएं जो आप चाहते हैं उसका समर्थन नहीं करते हैं, बिना काम के इर्द-गिर्द लागू किए बिना। (एसक्यूएल सर्वर में, फुल टेक्स्ट इंडेक्सिंग हेल्प?)
फिलिप केली

@Philip Kelley, SQL सर्वर का फुल टेक्स्ट इंडेक्सिंग कर सकता है LIKE 'bla%' , जो ओपी के उदाहरण कोड में है? या केवल LIKE '%bla%'खोजों में कर सकते हैं ?
के.एम.

मैं ईमानदारी से नहीं जानता, मैंने कभी भी एफटी इंडेक्सिंग का उपयोग नहीं किया है। मैंने इसे एक संभावित कार्य के नमूने के रूप में उछाला है-जो उत्पाद में पहले से ही शामिल है। वह क्या कर रहा है (ए या बी या सी), मुझे संदेह है कि वह ऐसा नहीं करता है , मुझे पूरा विश्वास है कि इसे निर्धारित करने के लिए बहुत प्रयास करना होगा, और यह जानना चाहिए कि इसके मूल प्रश्न के दायरे के बाहर (करता है) SQL इसे मूल रूप से करता है)।
फिलिप केली

20

PostgreSQL के साथ ANYया ALLरूप है:

WHERE col LIKE ANY( subselect )

या

WHERE col LIKE ALL( subselect )

जहाँ सबसेलेक्ट डेटा का एक स्तंभ देता है।


1
कर रहे हैं LIKE ANYऔर LIKE ALLकोर भाषा, या एक बोली के लिए विशिष्ट की यानी हिस्सा सभी एसक्यूएल बोलियों के लिए आम,?
असद इब्राहिम

1
@AssadEbrahim, नहीं वे विशिष्ट नहीं हैं। Oracle के पास = ANYया <> ALLकेवल SQL में काम करता है, उदाहरण के लिए PLSQL में नहीं।
बेनोइट

मुझे लगता है कि यह मानक वाक्यविन्यास है (लेकिन कई DBMS ने इसे लागू नहीं किया है)
ypercube

पोस्टग्रैज के लिए देखें stackoverflow.com/questions/2245536/…
rogerdpack

13

एक अन्य समाधान, किसी भी RDBMS पर काम करना चाहिए:

WHERE EXISTS (SELECT 1
                FROM (SELECT 'bla%' pattern FROM dual UNION ALL
                      SELECT '%foo%'        FROM dual UNION ALL
                      SELECT 'batz%'        FROM dual)
               WHERE something LIKE pattern)

1
लेकिन यह OR कथन के एक सेट की तुलना में बदसूरत है
Fandango68

1
@ Fandango68, लेकिन चयन का संघ एक अन्य स्रोत जैसे तालिका, एक दृश्य, आदि द्वारा प्रतिस्थापित किया जा सकता है
mik

10

यदि आप इनर जॉइन या टेम्‍प टेबल तकनीकों को ऊपर दर्शाना चाहते हैं तो मैं एक टेबलवैलू यूजर फंक्शन का उपयोग करने का सुझाव दूंगा। यह इसे और अधिक स्पष्ट रूप से पढ़ने की अनुमति देगा।

: विभाजन समारोह इस्तेमाल करने के बाद में परिभाषित http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx

हम "मछली" (इंट आईडी, varchar (50) नाम) नामक एक तालिका के आधार पर निम्नलिखित लिख सकते हैं

SELECT Fish.* from Fish 
    JOIN dbo.Split('%ass,%e%',',') as Splits 
    on Name like Splits.items  //items is the name of the output column from the split function.

आउटपुट

1 बास
2 पाईक
7 अंगरेज
8 वाल्लेये

1
यदि एक बार में कई शर्तों से मिलान किया जाता है तो एक पंक्ति को दोहराया जाएगा।
mik

7

एक दृष्टिकोण एक अस्थायी तालिका (या SQL सर्वर में तालिका चर) में शर्तों को संग्रहीत करने और इस तरह से शामिल होने के लिए होगा:

SELECT t.SomeField
FROM YourTable t
   JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue

यदि एक बार में कई शर्तों से मिलान किया जाता है तो एक पंक्ति को दोहराया जाएगा।
mik

7

इसके बजाय एक आंतरिक जुड़ाव का उपयोग करें:

SELECT ...
FROM SomeTable
JOIN
(SELECT 'bla%' AS Pattern 
UNION ALL SELECT '%foo%'
UNION ALL SELECT 'batz%'
UNION ALL SELECT 'abc'
) AS Patterns
ON SomeTable.SomeColumn LIKE Patterns.Pattern

1
खैर, यह वही है जो मैं बचना चाहूंगा। हालांकि यह काम करता है।
आत्मवारेसुप

इस समाधान से क्यों बचें? यह स्वीकृत समाधान के रूप में तेजी से काम करता है, और बस के रूप में बहुमुखी है।
फिल फैक्टर

3
@PhilFactor यह समाधान डुप्लिकेट पंक्तियाँ बना सकता है।
जैकब कानिया

5

मैं यहाँ SQl सर्वर और Oracle के साथ काम कर रहा हूँ, लेकिन मुझे दिलचस्पी है अगर यह किसी भी RDBMS में संभव है।

Teradata सभी / किसी भी वाक्यविन्यास का समर्थन करता है :

सूची में सभी स्ट्रिंग। सूची में
कोई भी स्ट्रिंग।

┌──────────────────────────────┬────────────────────────────────────┐
      THIS expression         IS equivalent to this expression  
├──────────────────────────────┼────────────────────────────────────┤
 x LIKE ALL ('A%','%B','%C%')  x LIKE 'A%'                        
                               AND x LIKE '%B'                    
                               AND x LIKE '%C%'                   
                                                                  
 x LIKE ANY ('A%','%B','%C%')  x LIKE 'A%'                        
                               OR x LIKE '%B'                     
                               OR x LIKE '%C%'                    
└──────────────────────────────┴────────────────────────────────────┘

संपादित करें:

jOOQ संस्करण 3.12.0 उस सिंटैक्स का समर्थन करता है:

सिंथेटिक जोड़ें [नहीं] किसी को पसंद करें और सभी ऑपरेटरों को पसंद न करें

बहुत बार, SQL उपयोगकर्ता LIKE और IN विधेयकों को संयोजित करने में सक्षम होना चाहते हैं, जैसे:

SELECT *
FROM customer
WHERE last_name [ NOT ] LIKE ANY ('A%', 'E%') [ ESCAPE '!' ]

वर्कअराउंड मैन्युअल रूप से विधेय के समतुल्य का विस्तार करना है

SELECT *
FROM customer
WHERE last_name LIKE 'A%'
OR last_name LIKE 'E%'

jOOQ बॉक्स के बाहर इस तरह के सिंथेटिक विधेय का समर्थन कर सकता है।


PostgreSQL LIKE/ILIKE ANY (ARRAY[]):

SELECT *
FROM t
WHERE c LIKE ANY (ARRAY['A%', '%B']);

SELECT *
FROM t
WHERE c LIKE ANY ('{"Do%", "%at"}');

db <> फिडेल डेमो


स्नोफ्लेक किसी भी तरह का समर्थन करता है / सभी मिलान पसंद करता है :

किसी भी / सभी तरह की

एक या अधिक पैटर्न के साथ तुलना के आधार पर केस-संवेदी मिलान की अनुमति देता है

<subject> LIKE ANY (<pattern1> [, <pattern2> ... ] ) [ ESCAPE <escape_char> ]

उदाहरण:

SELECT * 
FROM like_example 
WHERE subject LIKE ANY ('%Jo%oe%','T%e')
-- WHERE subject LIKE ALL ('%Jo%oe%','J%e')

4

यू भी यह कोशिश कर सकते हैं

समारोह

CREATE  FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20))
RETURNS @Strings TABLE
(   
  position int IDENTITY PRIMARY KEY,
  value varchar(8000)  
)
AS
BEGIN

DECLARE @index int
SET @index = -1

WHILE (LEN(@text) > 0)
  BEGIN 
    SET @index = CHARINDEX(@delimiter , @text) 
    IF (@index = 0) AND (LEN(@text) > 0) 
      BEGIN  
        INSERT INTO @Strings VALUES (@text)
          BREAK 
      END 
    IF (@index > 1) 
      BEGIN  
        INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))  
        SET @text = RIGHT(@text, (LEN(@text) - @index)) 
      END 
    ELSE
      SET @text = RIGHT(@text, (LEN(@text) - @index))
    END
  RETURN
END

सवाल

select * from my_table inner join (select value from fn_split('ABC,MOP',','))
as split_table on my_table.column_name like '%'+split_table.value+'%';

4

मेरे पास एक सरल समाधान है, जो कम से कम पोस्टग्रैक्स्ल में काम करता है , like anyरेगेक्स की सूची के बाद। यहाँ एक उदाहरण है, एक सूची में कुछ एंटीबायोटिक दवाओं की पहचान:

select *
from database.table
where lower(drug_name) like any ('{%cillin%,%cyclin%,%xacin%,%mycine%,%cephal%}')

3

मैं भी कुछ ऐसा ही सोच रहा था। मैं बस के संयोजन का उपयोग परीक्षण किया SUBSTRINGऔर INऔर यह इस तरह की समस्या के लिए एक प्रभावी समाधान है। नीचे दिए गए प्रश्न का प्रयास करें:

Select * from TB_YOUR T1 Where SUBSTRING(T1.Something, 1,3) IN ('bla', 'foo', 'batz')

1
इस दृष्टिकोण के साथ एक मुद्दा यह है कि अगर यह मौजूद है तो t1.something पर एक इंडेक्स का उपयोग करने की क्षमता ढीली है
जूतालॉस

1
यह 'batz'
mik

3

में ओरेकल आप निम्नलिखित तरीके से एक संग्रह का उपयोग कर सकते हैं:

WHERE EXISTS (SELECT 1
                FROM TABLE(ku$_vcnt('bla%', '%foo%', 'batz%'))
               WHERE something LIKE column_value)

यहाँ मैंने एक पूर्वनिर्धारित संग्रह प्रकार का उपयोग किया है ku$_vcnt, लेकिन आप इस तरह से अपनी खुद की घोषणा कर सकते हैं:

CREATE TYPE my_collection AS TABLE OF VARCHAR2(4000);

2

Sql Server के लिए आप डायनेमिक SQL का सहारा ले सकते हैं।

ऐसी स्थितियों में अधिकांश समय आपके पास डेटाबेस से कुछ डेटा के आधार पर IN खंड का पैरामीटर होता है।

नीचे दिया गया उदाहरण थोड़ा "मजबूर" है, लेकिन यह विरासत डेटाबेस में पाए जाने वाले विभिन्न वास्तविक मामलों से मेल खा सकता है।

मान लीजिए कि आपके पास टेबल पर्सन हैं, जहां व्यक्ति के नाम एक ही क्षेत्र पर्सननेम में फर्स्टनाम + '+ लास्टनाम के रूप में संग्रहीत हैं । आपको पहले नामों की सूची से सभी व्यक्तियों का चयन करने की आवश्यकता है, नाम NameToSelect में तालिका NamesToSelect में संग्रहीत , प्लस कुछ अतिरिक्त मानदंड (जैसे लिंग, जन्म तिथि, आदि पर फ़िल्टर्ड)

आप इसे निम्नानुसार कर सकते हैं

-- @gender is nchar(1), @birthDate is date 

declare 
  @sql nvarchar(MAX),
  @subWhere nvarchar(MAX)
  @params nvarchar(MAX)

-- prepare the where sub-clause to cover LIKE IN (...)
-- it will actually generate where clause PersonName Like 'param1%' or PersonName Like 'param2%' or ...   
set @subWhere = STUFF(
  (
    SELECT ' OR PersonName like ''' + [NameToSelect] + '%''' 
        FROM [NamesToSelect] t FOR XML PATH('')
  ), 1, 4, '')

-- create the dynamic SQL
set @sql ='select 
      PersonName
      ,Gender
      ,BirstDate    -- and other field here         
  from [Persons]
  where 
    Gender = @gender
    AND BirthDate = @birthDate
    AND (' + @subWhere + ')'

set @params = ' @gender nchar(1),
  @birthDate Date'     

EXECUTE sp_executesql @sql, @params,    
  @gender,  
  @birthDate

2

मेरे पास इसके लिए एक समाधान हो सकता है, हालांकि यह केवल SQL सर्वर 2008 में काम करेगा जहां तक ​​मुझे पता है। मुझे पता चला कि आप https://stackoverflow.com/a/7285095/894974 में वर्णित पंक्ति-कंस्ट्रक्टर का उपयोग एक 'क्लाज़' जैसे क्लॉज़ में शामिल होने के लिए कर सकते हैं । यह अधिक जटिल लगता है तो यह है, देखो:

SELECT [name]
  ,[userID]
  ,[name]
  ,[town]
  ,[email]
FROM usr
join (values ('hotmail'),('gmail'),('live')) as myTable(myColumn) on email like '%'+myTable.myColumn+'%' 

यह सभी उपयोगकर्ताओं को सूची में प्रदान किए गए ई-मेल एड्रे के समान होगा। आशा है कि यह किसी के लिए भी उपयोग हो। समस्या मुझे कुछ समय से परेशान कर रही थी।


1
यह तो दिलचस्प है। हालाँकि, इस बात का ध्यान रखें कि इसका उपयोग केवल स्माल टेबल पर ही किया जाना चाहिए क्योंकि जैसा स्टेटमेंट इंडेक्स का उपयोग नहीं कर सकता है। यही कारण है कि पूर्ण पाठ खोज, जबकि कठिन से बेहतर सेट अप करना, बेहतर विकल्प है यदि आपके पास डेटा का एक बहुत है।
HLGEM

2

2016 के साथ शुरू, SQL सर्वर में एक STRING_SPLIT फ़ंक्शन शामिल है । मैं SQL सर्वर v17.4 का उपयोग कर रहा हूं और मुझे यह मेरे लिए काम करने के लिए मिला है:

DECLARE @dashboard nvarchar(50)
SET @dashboard = 'P1%,P7%'

SELECT * from Project p
JOIN STRING_SPLIT(@dashboard, ',') AS sp ON p.ProjectNumber LIKE sp.value


1

यह अल्पविराम द्वारा अलग किए गए मानों के लिए काम करता है

DECLARE @ARC_CHECKNUM VARCHAR(MAX)
SET @ARC_CHECKNUM = 'ABC,135,MED,ASFSDFSF,AXX'
SELECT ' AND (a.arc_checknum LIKE ''%' + REPLACE(@arc_checknum,',','%'' OR a.arc_checknum LIKE ''%') + '%'')''

का मूल्यांकन:

 AND (a.arc_checknum LIKE '%ABC%' OR a.arc_checknum LIKE '%135%' OR a.arc_checknum LIKE '%MED%' OR a.arc_checknum LIKE '%ASFSDFSF%' OR a.arc_checknum LIKE '%AXX%')

यदि आप इसे इंडेक्स का उपयोग करना चाहते हैं, तो आपको पहले '%'वर्ण को छोड़ना होगा ।


1

Oracle RBDMS में आप REGEXP_LIKE फ़ंक्शन का उपयोग करके इस व्यवहार को प्राप्त कर सकते हैं ।

निम्न कोड परीक्षण करेगा यदि स्ट्रिंग तीन सूची अभिव्यक्ति एक में मौजूद है | दो | तीन | चार | पांच (जिसमें पाइप " | " प्रतीक का अर्थ है या तर्क ऑपरेशन)।

SELECT 'Success !!!' result
FROM dual
WHERE REGEXP_LIKE('three', 'one|two|three|four|five');

RESULT
---------------------------------
Success !!!

1 row selected.

पूर्ववर्ती अभिव्यक्ति इसके बराबर है:

three=one OR three=two OR three=three OR three=four OR three=five

तो यह सफल होगा।

दूसरी ओर, निम्नलिखित परीक्षा विफल हो जाएगी।

SELECT 'Success !!!' result
FROM dual
WHERE REGEXP_LIKE('ten', 'one|two|three|four|five');

no rows selected

Oracle में 10g संस्करण के बाद से नियमित अभिव्यक्ति (REGEXP_ *) से संबंधित कई कार्य उपलब्ध हैं। यदि आप एक Oracle डेवलपर हैं और इस विषय में रुचि रखते हैं , तो Oracle डेटाबेस के साथ रेगुलर एक्सप्रेशंस का उपयोग करते हुए यह एक अच्छी शुरुआत होनी चाहिए ।


1

क्या आपको लगता है कि संयोजन इस तरह से हो सकता है:

SELECT  * 
FROM    table t INNER JOIN
(
  SELECT * FROM (VALUES('bla'),('foo'),('batz')) AS list(col)
) l ON t.column  LIKE '%'+l.Col+'%'

यदि आपने अपनी लक्ष्य तालिका के लिए पूर्ण पाठ सूचकांक निर्धारित किया है तो आप इस विकल्प का उपयोग कर सकते हैं:

SELECT  * 
FROM    table t
WHERE CONTAINS(t.column, '"bla*" OR "foo*" OR "batz*"')

धन्यवाद। यह स्वीकृत जवाब IMO होना चाहिए। सभी के पास परिभाषित पूर्ण पाठ सूचकांक नहीं है (जो भी इसका मतलब है) आपका पहला सुझाव एक आकर्षण की तरह काम करता है। यहां तक ​​कि आप वाइल्डकार्ड को LIKE पर कॉन्टेक्ट करने के बजाय टेम्प टेबल टेबल वैल्यू में डाल सकते हैं।
मूर्ख


0

Teradata में आप उपयोग कर सकते हैं LIKE ANY ('%ABC%','%PQR%','%XYZ%')। नीचे एक उदाहरण दिया गया है जिसने मेरे लिए समान परिणाम तैयार किए हैं

--===========
--  CHECK ONE
--===========
SELECT *
FROM Random_Table A
WHERE (Lower(A.TRAN_1_DSC) LIKE ('%american%express%centurion%bank%')
OR Lower(A.TRAN_1_DSC) LIKE ('%bofi%federal%bank%')
OR Lower(A.TRAN_1_DSC) LIKE ('%american%express%bank%fsb%'))

;
--===========
--  CHECK TWO
--===========
SELECT *
FROM Random_Table  A
WHERE Lower(A.TRAN_1_DSC) LIKE ANY 
('%american%express%centurion%bank%',
'%bofi%federal%bank%',
'%american%express%bank%fsb%')

0

मुझे पता है कि यह बहुत देर हो चुकी है, लेकिन मेरे पास एक समान स्थिति थी। मेरे पास संग्रहीत प्रक्रियाओं के एक सेट के लिए "लाइक इन" ऑपरेटर की आवश्यकता है, जो कई मापदंडों को स्वीकार करते हैं और फिर कई आरडीबीएमएस सिस्टम से डेटा एकत्र करने के लिए उन मापदंडों का उपयोग करते हैं, इस प्रकार कोई आरडीबीएमएस-विशिष्ट चालें काम नहीं करेगी, हालांकि संग्रहीत कार्यविधि और कोई कार्य MS SQL सर्वर पर चलेगा, इसलिए हम प्रत्येक RDBMS के लिए पूर्ण SQL स्टेटमेंट बनाने की कार्यक्षमता के लिए T-SQL का उपयोग कर सकते हैं, लेकिन आउटपुट को काफी RDBMS- स्वतंत्र होना चाहिए।

यह वह समय है जब मैं एक सीमांकित स्ट्रिंग (जैसे कि एक पैरामीटर एक संग्रहीत प्रक्रिया में आने वाला पैरामीटर) को एसक्यूएल के ब्लॉक में बदल देता हूं। मैं इसे "LIKE IN" के लिए "लिचेन" कहता हूं। उसे ले लो?

Lichen.sql

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =======================================================================
-- Lichen - Scalar Valued Function
-- Returns nvarchar(512) of "LIKE IN" results.  See further documentation.
-- CREATOR: Norman David Cooke
-- CREATED: 2020-02-05
-- UPDATED:
-- =======================================================================
CREATE OR ALTER FUNCTION Lichen 
(
    -- Add the parameters for the function here
    @leadingAnd bit = 1,
    @delimiter nchar(1) = ';',
    @colIdentifier nvarchar(64),
    @argString nvarchar(256)
)
RETURNS nvarchar(512)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @result nvarchar(512)

    -- set delimiter to detect (add more here to detect a delimiter if one isn't provided)
    DECLARE @delimit nchar(1) = ';'
    IF NOT @delimiter = @delimit 
        SET @delimit = @delimiter


    -- check to see if we have any delimiters in the input pattern
    IF CHARINDEX(@delimit, @argString) > 1  -- check for the like in delimiter
    BEGIN  -- begin 'like in' branch having found a delimiter
        -- set up a table variable and string_split the provided pattern into it.
        DECLARE @lichenTable TABLE ([id] [int] IDENTITY(1,1) NOT NULL, line NVARCHAR(32))
        INSERT INTO @lichenTable SELECT * FROM STRING_SPLIT(@argString, ';')

        -- setup loop iterators and determine how many rows were inserted into lichen table
        DECLARE @loopCount int = 1
        DECLARE @lineCount int 
        SELECT @lineCount = COUNT(*) from @lichenTable

        -- select the temp table (to see whats inside for debug)
        --select * from @lichenTable

        -- BEGIN AND wrapper block for 'LIKE IN' if bit is set
        IF @leadingAnd = 1
            SET @result = ' AND ('
        ELSE
            SET @result = ' ('

        -- loop through temp table to build multiple "LIKE 'x' OR" blocks inside the outer AND wrapper block
        WHILE ((@loopCount IS NOT NULL) AND (@loopCount <= @lineCount))
        BEGIN -- begin loop through @lichenTable
            IF (@loopcount = 1) -- the first loop does not get the OR in front
                SELECT @result = CONCAT(@result, ' ', @colIdentifier, ' LIKE ''', line, '''') FROM @lichenTable WHERE id = @loopCount
            ELSE  -- but all subsequent loops do
                SELECT @result = CONCAT(@result, ' OR ', @colIdentifier, ' LIKE ''', line, '''') FROM @lichenTable WHERE id = @loopCount
            SET @loopcount = @loopCount + 1     -- increment loop
        END -- end loop through @lichenTable

        -- set final parens after lichenTable loop
        SET @result = CONCAT(@result, ' )')
    END  -- end 'like in' branch having found a delimiter
    ELSE -- no delimiter was provided
    BEGIN   -- begin "no delimiter found" branch
        IF @leadingAnd = 1 
            SET @result = CONCAT(' AND ', @colIdentifier, ' LIKE ''' + @argString + '''')
        ELSE
            SET @result = CONCAT(' ', @colIdentifier, ' LIKE ''' + @argString + '''')
    END     -- end "no delimiter found" branch

    -- Return the result of the function
    RETURN @result
END  -- end lichen function

GO

सीमांकक का पता लगाने की योजना बनाई गई है, लेकिन अब यह अर्धविराम के लिए डिफॉल्ट करता है इसलिए आप बस defaultवहां डाल सकते हैं । इसमें शायद कीड़े हैं। @leadingAndपैरामीटर तय करें कि आप ब्लॉक के सामने एक अग्रणी "और" पुट चाहते तो यह अन्य कहां खंड परिवर्धन के साथ अच्छी तरह से फिट बैठता है में बस थोड़ा मूल्य है।

उदाहरण उपयोग (argString में सीमांकक के साथ)

SELECT [dbo].[Lichen] (
   default        -- @leadingAND, bit, default: 1
  ,default        -- @delimiter, nchar(1), default: ';'
  ,'foo.bar'      -- @colIdentifier, nvarchar(64), this is the column identifier
  ,'01%;02%;%03%' -- @argString, nvarchar(256), this is the input string to parse "LIKE IN" from
)
GO

एक nvarchar (512) से युक्त होगा:

 AND ( foo.bar LIKE '01%' OR foo.bar LIKE '02%' OR foo.bar LIKE '%03%' ) 

यदि इनपुट में सीमांकक नहीं है तो यह ब्लॉक को भी छोड़ देगा:

उदाहरण का उपयोग (बिना सीमांकक के)

SELECT [dbo].[Lichen] (
   default        -- @leadingAND, bit, default: 1
  ,default        -- @delimiter, nchar(1), default: ';'
  ,'foo.bar'      -- @colIdentifier, nvarchar(64), this is the column identifier
  ,'01%'          -- @argString, nvarchar(256), this is the input string to parse "LIKE IN" from
)
GO

एक nvarchar (512) से युक्त होगा:

 AND foo.bar LIKE '01%'

मैं इस पर काम जारी रखने जा रहा हूं, इसलिए यदि मैंने कुछ (स्पष्ट रूप से स्पष्ट या अन्यथा) अनदेखी की है, तो कृपया टिप्पणी करने या पहुंचने के लिए स्वतंत्र महसूस करें।


-3

यह करो

WHERE something + '%' in ('bla', 'foo', 'batz')
OR '%' + something + '%' in ('tra', 'la', 'la')

या

WHERE something + '%' in (select col from table where ....)

1
कैसे काम करने जा रहा है? LHS एक% के साथ एक स्ट्रिंग है, और वह% इसलिए वाइल्डकार्ड नहीं है
Darius X.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.