1

I have declare @a varchar(100) = 'abc bcd cde def'. What I need is to select from a table where a column is like 'abc' or 'bcd' or 'cde' or 'def'. I can use a split function and a while to get what I want, but somewhere I saw a smart solution using replace or something similar and I just can't remember it.

I know I can use an xml variable, and parse it that way. However, the value is part of a large procedure, and the best way for me is to use it in string form.

I know I can solve this by building a dynamic sql query, but that is not an option in the domain I'm working in.

4 Answers4

1

Damn, I just can remember the solution. Its a hack, a little dirty trick that do the job.

Anyways, I ll use the code bellow (Im over SQL Server 2008), is it a good idea? I prefer it over the dirty split. Is it more performatic?

declare @w varchar(100) = 'some word'
declare @f xml

set @f = '<word>' + replace(@w, ' ', '</word><word>') + '</word>'

select
    template.item.value('.', 'varchar(100)') as word
from @f.nodes('/word') template(item)
0

In tsql you can use a pattern col like '[abcd]'

http://msdn.microsoft.com/en-us/library/ms179859.aspx

For matching multiple words (not letter) and without dynamic SQL, you'll have to get the values into a temp table. For a split function try this page http://www.sommarskog.se/arrays-in-sql-2005.html#iterative and look at the List of Strings function iter_charlist_to_table.

Or maybe you are thinking of this little trick Parameterize an SQL IN clause from the SO CEO.

Community
  • 1
  • 1
dotjoe
  • 26,242
  • 5
  • 63
  • 77
  • Note: This matches individual characters. If you wanted to match words, this wouldn't work. – MatBailie Nov 08 '11 at 19:38
  • I think you nailed it. Let me take a deep look. Thankx. What do you think about my dirty xml based technique? –  Nov 08 '11 at 20:31
  • personally I'd do the split-to-table function, but I never really used xml variable in sql server so I can't say which is faster. – dotjoe Nov 08 '11 at 20:50
0

Use a function to split the individual items into a table, one record per item. Then you simply join to that table.

insert into #FilterTable (filters)
select Items from dbo.Split(@YourFilterString)

select * 
  from YourTable yt
  join #FilterTable f on f.filters = yt.YourColumn

Of course my example is using equality. It gets more complicated if you truly intend to use "like" with wildcards.

datagod
  • 1,031
  • 1
  • 13
  • 21
0

for 4 sections max

WHERE
    PARSENAME(REPLACE(@a, ' ', '.'), 1) = 'xxx'
    OR
    PARSENAME(REPLACE(@a, ' ', '.'), 2) = 'xxx'
    OR
    PARSENAME(REPLACE(@a, ' ', '.'), 3) = 'xxx'
    OR
    PARSENAME(REPLACE(@a, ' ', '.'), 4) = 'xxx'
gbn
  • 422,506
  • 82
  • 585
  • 676