how to check word within a string using regex in snowflake - snowflake-cloud-data-platform

I am trying to find a exact string within a string using rexexp_like or rlike
column 1 :-'houses for rent in asher ok'
column 2:-'houses','house','rental','ok'
output should be true,false,false,true
tried below options:
regexp_like(col1, concat(col2,'.*')) -->failing for 'ok'
regexp_like(col1, concat(concat('\b,col2,'\b'))
tried rlike also, but of no use. CAN SOMEONE HELP ME

Standard LIKE is enough:
SELECT *, table1.column1 ILIKE CONCAT('%', table2.column2, '%')
FROM table1
CROSS JOIN table2;
Output:

Related

SQL Server - Find out if string returned in subquery contains another string

I have two tables. One has a separate rows for each ID. The other has a string with a comma separated list of IDs. I'm trying to find out if the ID from the first table appears anywhere within the string of comma separated IDs in the second table.
Here's a sample (non-working) query:
select * from
(select 'b' as ID) table1
where table1.ID in
(select 'a,b,c' as CSV_LIST)
This is not how IN works, of course, but I don't know how else to approach this.
I've thought about using STRING_SPLIT() but it doesn't work in this version of SQL Server. I've also thought about using CONTAINS() but I can't seem to get it to work either.
Any ideas?
You can use LIKE or a custom string splitter like Jeff Moden's if you can't fix the design.
select table1.*
from table1
inner join table2
on table2.csv like '%' + table1.b + '%'
Note, this isn't SARGable because of the leading % so as Sean pointed out, fixing the design would be best, followed by another split function that doesn't use a WHILE loop.

SQL Server : make a select and test every occurrence/row inside another select

I have a SQL Server stored procedure that receives a comma separated string as parameter.
I also have a table-valued function that takes this parameter, splits it (between the commas) and returns as a 'table'.
This procedures is a 'search procedure' that uses LIKE operator to find matching terms.
How can I loop through this parameter that has been transformed into a table and compare it with LIKE?
The sequence that I'd need is something like this:
SQL Server procedure has been called and a separated comma string has been passed as parameter.
A table-valued function gets called to strip this string and transform it in a result table. (It´s not a real table, its just the results). Until here I have already done, the next part is the one I need help:
Loop through this recently created 'table' and search in a specific column of another table.
eg.
SELECT *
FROM tbl_names
WHERE col_names LIKE '%' + (the search term here) + '%'
You can join your table on result of your function:
select * from SomeTable st
join dbo.SomeFunction(#str) sf on st.SomeColumn like '%' + sf.Term +'%'
To order by occurences do something like this:
select * from SomeTable st
join(
select st.ID, count(*) as Occurence from SomeTable st
join dbo.SomeFunction(#str) sf on st.SomeColumn like '%' + sf.Term +'%'
group by st.ID) ot on st.ID = ot.ID
order by ot.Occurence desc
I'd probably use a cross or outer apply with patindex if you want to know how many items matched
select S.*, m.matches
from sometable s
cross apply (select count(1) as matches from finction where patindex ('%' + function.Column + '%', s.coltosearch) > 1) as matched
Use cross apply if you only want to return rows that have matches and outer if you want all rows with a count of terms.
Note: Code example is untested

Check for string in column but restrict for certain words

I have a SQL procedure that checks for a certain String in a column like
SELECT [text_field] FROM [dbo].[tbl_a] (NOLOCK) WHERE [text_field] LIKE '%search%'
But how can I restrict this query to show results for %search% but not for searching?
The same applies the other way if I search for %happy% but not unhappy
Why not
SELECT [field] FROM [dbo].[TABLE] (NOLOCK) WHERE [field] = "search"
The following SQL statement selects all customers with a Country containing the pattern "search":
Why you don't use this?:
SELECT [text_field] FROM [dbo].[tbl_a] (NOLOCK) WHERE [text_field] = "search"
For more information to
LIKE
EDIT
SELECT [text_field] FROM [dbo].[tbl_a] (NOLOCK) WHERE [text_field] LIKE '%search%' AND [textfield] NOT LIKE '%unhappy%'
Try using
Contains
SELECT [text_field] FROM [dbo].[tbl_a] WHERE Contains([text_field],'search')
This query is only available if the column is in a full text index. You have to assign full-text index to your text-field column .
Here
I ended up using
SELECT [textfield] FROM [tbl_a] (NOLOCK) WHERE [textfield] like '%[^a-z]search[^a-z]%';
I first query
WHERE [textfield] like '%search%'
then I create a list of all words containing 'search' from that result
Next I loop over the selected words e.g. 'searching' but not 'Researching'

LIKE comparison with IN operator

I want to perform a LIKE style comparison with an IN operator e.g.:
select *
from tbl1
where tbl1.value_to_check in (select allowed_str from allowedvalues)
Where allowed values could contain the following allowed_str:
ab% (allow any string starting ab)
%ab (allow any string ending ab)
The above query obviously does not work in this way however is there a way of achieving this using SQL Server 2008?
No, IN does not support this. Try:
SELECT t1.*
FROM dbo.tbl1 AS t1
INNER JOIN dbo.allowedvalues AS a
ON t1.value_to_check LIKE '%' + a.allowed_str + '%';
As Damien points out, if you are storing ab% and %ab separately, rather than just ab on its own, then you just need:
SELECT t1.*
FROM dbo.tbl1 AS t1
INNER JOIN dbo.allowedvalues AS a
ON t1.value_to_check LIKE a.allowed_str;
I believe the exists clause matches better with the original query.
select *
from tbl1
where exists (select 1
from allowedvalues
where tbl1.value_to_check like '%' + a.allowed_str + '%';)
Note: this will cause a table scan on tbl1 (and might be very slow)

Select records with a substring from another table

I have this two tables:
data
id |email
_
1 |xxx#gmail.com
2 |yyy#gmial.com
3 |zzzgimail.com
errors
_
error |correct
#gmial.com|#gmail.com
gimail.com|#gmail.com
How can I select from data all the records with an email error? Thanks.
SELECT d.id, d.email
FROM data d
INNER JOIN errors e ON d.email LIKE '%' + e.error
Would do it, however doing a LIKE with a wildcard at the start of the value being matched on will prevent an index from being used so you may see poor performance.
An optimal approach would be to define a computed column on the data table, that is the REVERSE of the email field and index it. This would turn the above query into a LIKE condition with the wildcard at the end like so:
SELECT d.id, d.email
FROM data d
INNER JOIN errors e ON d.emailreversed LIKE REVERSE(e.error) + '%'
In this case, performance would be better as it would allow an index to be used.
I blogged a full write up on this approach a while ago here.
Assuming the error is always at the end of the string:
declare #data table (
id int,
email varchar(100)
)
insert into #data
(id, email)
select 1, 'xxx#gmail.com' union all
select 2, 'yyy#gmial.com' union all
select 3, 'zzzgimail.com'
declare #errors table (
error varchar(100),
correct varchar(100)
)
insert into #errors
(error, correct)
select '#gmial.com', '#gmail.com' union all
select 'gimail.com', '#gmail.com'
select d.id,
d.email,
isnull(replace(d.email, e.error, e.correct), d.email) as CorrectedEmail
from #data d
left join #errors e
on right(d.email, LEN(e.error)) = e.error
Well, in reality you can't with the info you have provided.
In SQL you would need to maintain a table of "correct" domains. With that you could do a simple query to find non-matches.
You could use some "non" SQL functionality in SQL Server to do a regular expression check, however that kind of logic does not below in SQL (IMO).
select * from
(select 1 as id, 'xxx#gmail.com' as email union
select 2 as id, 'yyy#gmial.com' as email union
select 3 as id, 'zzzgimail.com' as email) data join
(select '#gmial.com' as error, '#gmail.com' as correct union
select 'gimail.com' as error, '#gmail.com' as correct ) errors
on data.email like '%' + error + '%'
I think ... that if you didn't use a wildcard at the beginning but anywhere after, it could benefit from an index. If you used a full text search, it could benefit too.

Resources