Is there a combination of “LIKE” and “IN” in SQL?

后端 未结 25 1618
灰色年华
灰色年华 2020-11-22 03:08

In SQL I (sadly) often have to use \"LIKE\" conditions due to databases that violate nearly every rule of normalization. I can\'t change that right now. But tha

相关标签:
25条回答
  • 2020-11-22 03:55

    May be you think the combination like this:

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

    If you have defined full text index for your target table then you may use this alternative:

    SELECT  * 
    FROM    table t
    WHERE CONTAINS(t.column, '"bla*" OR "foo*" OR "batz*"')
    
    0 讨论(0)
  • 2020-11-22 03:56

    Another solution, should work on any 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)
    

    The inner select can be replaced by another source of patterns like a table (or a view) in this way:

    WHERE EXISTS (SELECT 1
                    FROM table_of_patterns t
                   WHERE something LIKE t.pattern)
    

    table_of_patterns should contain at least a column pattern, and can be populated like this:

    INSERT INTO table_of_patterns(pattern) VALUES ('bla%');
    INSERT INTO table_of_patterns(pattern) VALUES ('%foo%');
    INSERT INTO table_of_patterns(pattern) VALUES ('batz%');
    
    0 讨论(0)
  • 2020-11-22 03:56

    I'm working with SQl Server and Oracle here but I'm interested if this is possible in any RDBMS at all.

    Teradata supports LIKE ALL/ANY syntax:

    ALL every string in the list.
    ANY any string in the list.

    ┌──────────────────────────────┬────────────────────────────────────┐
    │      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%'                    │
    └──────────────────────────────┴────────────────────────────────────┘
    

    EDIT:

    jOOQ version 3.12.0 supports that syntax:

    Add synthetic [NOT] LIKE ANY and [NOT] LIKE ALL operators

    A lot of times, SQL users would like to be able to combine LIKE and IN predicates, as in:

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

    The workaround is to manually expand the predicate to the equivalent

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

    jOOQ could support such a synthetic predicate out of the box.


    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<>fiddle demo


    Snowflake also supports LIKE ANY/LIKE ALL matching:

    LIKE ANY/ALL

    Allows case-sensitive matching of strings based on comparison with one or more patterns.

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

    Example:

    SELECT * 
    FROM like_example 
    WHERE subject LIKE ANY ('%Jo%oe%','T%e')
    -- WHERE subject LIKE ALL ('%Jo%oe%','J%e')
    
    0 讨论(0)
  • 2020-11-22 03:56

    Starting with 2016, SQL Server includes a STRING_SPLIT function. I'm using SQL Server v17.4 and I got this to work for me:

    DECLARE @dashboard nvarchar(50)
    SET @dashboard = 'P1%,P7%'
    
    SELECT * from Project p
    JOIN STRING_SPLIT(@dashboard, ',') AS sp ON p.ProjectNumber LIKE sp.value
    
    0 讨论(0)
  • 2020-11-22 03:58

    I have a simple solution, that works in postgresql at least, using like any followed by the list of regex. Here is an example, looking at identifying some antibiotics in a list:

    select *
    from database.table
    where lower(drug_name) like any ('{%cillin%,%cyclin%,%xacin%,%mycine%,%cephal%}')
    
    0 讨论(0)
  • 2020-11-22 03:59

    This works for comma separated values

    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 ''%') + '%'')''
    

    Evaluates to:

     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%')
    

    If you want it to use indexes, you must omit the first '%' character.

    0 讨论(0)
提交回复
热议问题