Combination of 'LIKE' and 'IN' using t-sql

后端 未结 6 826
無奈伤痛
無奈伤痛 2020-12-13 18:12

How can I do this kind of selection:

SELECT * 
FROM Street 
WHERE StreetName LIKE IN (\'% Main Street\', \'foo %\')

Please don\'t tell me t

相关标签:
6条回答
  • 2020-12-13 18:26

    I believe I can clarify what he is looking for, but I don't know the answer. I'll use my situation to demonstrate. I have a table with a column called "Query" that holds SQL queries. These queries sometimes contain table names from one of my databases. I need to find all Query rows that contain table names from a particular database. So, I can use the following code to get the table names:

    SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
    

    I'm trying to use a WHERE IN clause to identify the Query rows that contain the table names I'm interested in:

    SELECT *
      FROM [DatasourceQuery]
     WHERE Query IN LIKE
    (
        SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
    )
    

    I believe the OP is trying to do something like that.

    0 讨论(0)
  • This is my way:

    First create a table function:

    create function [splitDelimeter](@str nvarchar(max), @delimeter nvarchar(10)='*')
    returns @r table(val nvarchar(max))
    as
    begin
    
        declare @x nvarchar(max)=@str
        set @x='<m>'+replace(@x, @delimeter, '</m><m>')+'</m>'
    
        declare @xx xml=cast(@x as xml)
    
        insert @r(val)
        SELECT Tbl.Col.value('.', 'nvarchar(max)') id
        FROM @xx.nodes('/m') Tbl(Col)
    
        return 
    end
    

    Then split the search text with your preference delimeter. After that you can do your select with left join as below:

      declare @s nvarchar(max)='% Main Street*foo %'
    
      select a.* from street a
         left join gen.splitDelimeter(@s, '*') b
            on a.streetname like b.val
      where val is not null
    
    0 讨论(0)
  • 2020-12-13 18:31

    There is no combined LIKE and IN syntax but you can use LIKE to JOIN onto your query as below.

    ;WITH Query(Result) As
    (
    SELECT '% Main Street' UNION ALL
    SELECT 'foo %'
    )
    SELECT DISTINCT s.* 
    FROM Street s
    JOIN Query q ON StreetName LIKE q.Result
    

    Or to use your example in the comments

    SELECT DISTINCT s.* 
    FROM Street s
    JOIN CarStreets cs ON s.StreetName LIKE cs.name + '%'
    WHERE cs.Streets = 'offroad'
    
    0 讨论(0)
  • 2020-12-13 18:37

    You don't have a lot of choices here.

    SELECT * FROM Street Where StreetName LIKE '% Main Street' OR StreetName LIKE 'foo %'
    

    If this is part of an existing, more complicated query (which is the impression I'm getting), you could create a table value function that does the checking for you.

    SELECT * FROM Street Where StreetName IN (dbo.FindStreetNameFunction('% Main Street|foo %'))
    

    I'd recommend using the simplest solution (the first). If this is nested inside a larger, more complicated query, post it and we'll take a look.

    0 讨论(0)
  • 2020-12-13 18:37

    You can resort to Dynamic SQL and wrapping up all in a stored procedure.

    If you get the LIKE IN param in a string as tokens with a certain separator, like

    '% Main Street,foo %,Another%Street'
    

    first you need to create a function that receives a list of LIKE "tokens" and returns a table of them.

    CREATE FUNCTION [dbo].[SplitList]
    (
      @list nvarchar(MAX),
      @delim nvarchar(5)
    )  
    RETURNS @splitTable table 
    (       
      value nvarchar(50)
    ) 
    AS BEGIN
      While (Charindex(@delim, @list)>0) Begin 
        Insert Into @splitTable (value)
          Select ltrim(rtrim(Substring(@list, 1, Charindex(@delim, @list)-1))) 
        Set @list = Substring(@list, Charindex(@delim, @list)+len(@delim), len(@list))
      End     
      Insert Into @splitTable (value) Select ltrim(rtrim(@list))
      Return
    END 
    

    Then in the SP you have the following code

    declare 
      @sql nvarchar(MAX),
      @subWhere nvarchar(MAX)
      @params nvarchar(MAX)
    
    -- prepare the where sub-clause to cover LIKE IN (...)
    -- it will actually generate where sub clause StreetName Like option1 or StreetName Like option2 or ...   
    set @subWhere = STUFF(
      (
        --(**)
        SELECT ' OR StreetName like ''' + value + '''' FROM SplitList('% Main Street,foo %,Another%Street', ',') 
          FOR XML PATH('')
      ), 1, 4, '')
    
    -- create the dynamic SQL
    set @sql ='select * from [Street]
      where 
        (' + @subWhere + ')
        -- and any additional query params here, if needed, like
        AND StreetMinHouseNumber = @minHouseNumber
        AND StreetNumberOfHouses between (@minNumberOfHouses and @maxNumberOfHouses)'
    
    set @params = ' @minHouseNumber nvarchar(5),
      @minNumberOfHouses int,
      @minNumberOfHouses int'     
    
    EXECUTE sp_executesql @sql, @params,    
      @minHouseNumber,
      @minNumberOfHouses,
      @minNumberOfHouses     
    

    Of course, if you have your LIKE IN parameters in another table or you gather it through a query, you can replace that in line (**)

    0 讨论(0)
  • 2020-12-13 18:39

    I had a similar conundrum but due to only needing to match the start of a string, I changed my 'like' to SUBSTRING as such:

    SELECT *  
    FROM codes  
    WHERE SUBSTRING(code, 1, 12) IN ('012316963429', '012315667849')  
    
    0 讨论(0)
提交回复
热议问题