How to match a column value against a string of any length? - sql

I have a table which stores company names and their homepage URLs. Like so:
CompanyName | CompanyURL
WalMart walmart.com
eBay UK www.ebay.co.uk
Amazon http://www.amazon.com
Sometimes people will submit a URL to my application such as http://www.ebay.co.uk/amazon
I want to see if the CompanyURL value is contained within the URL submitted by the user.
I would normally try to do this:
SELECT
*
FROM
dbo.Company
WHERE CompanyURL LIKE '%www.ebay.co.uk/amazonstore%'
Naturally the above won't work because the string is longer than the column value. What I'm really trying to accomplish is:
...
WHERE CompanyURL IS CONTAINED SOMEHWERE INSIDE 'www.ebay.co.uk/amazonstore' --- the URL provided by the user
Is is possible to do this in SQL Server 2014?

Declare #YourTable table (CompanyName varchar(50),CompanyURL varchar(50))
Insert Into #YourTable values
('WalMart','walmart.com'),
('eBay UK','ebay.co.uk'),
('Amazon','http://www.amazon.com')
Select *
From #YourTable
Where 'www.ebay.co.uk/amazonstore' like '%'+Replace(Replace(Replace(Replace(CompanyURL,'//',''),'http:',''),'https:',''),'www','')+'%'
Returns
CompanyName CompanyURL
eBay UK ebay.co.uk
Now, I would recommend that you normalize your CompanyURL data.
Update YourTable set CompanyURL = Replace(Replace(Replace(Replace(CompanyURL,'//',''),'http:',''),'https:',''),'www','')
So future searches would only be
Select *
From #YourTable
Where 'www.ebay.co.uk/amazonstore' like '%'+CompanyURL+'%'

You could use CHARINDEX, which avoids dealing with the messy % symbol (which has a special meaning in a URL).
If you are expecting the input to be a superstring of the CompanyURL in your table (i.e. you want to see if the supplied value contains a CompanyURL), use this:
WHERE CHARINDEX(CompanyURL, 'www.ebay.co.uk/amazonstore') != 0
If you are expecting the input to be a substring of the CompanyURL in your table (i.e. you want to see if any of your CompanyURL values contains the supplied value), use this:
WHERE CHARINDEX('www.ebay.co.uk/amazonstore', CompanyURL) != 0
If you need to detect both conditions, you can always use this
WHERE CHARINDEX('www.ebay.co.uk/amazonstore', CompanyURL) != 0
OR CHARINDEX(CompanyURL, 'www.ebay.co.uk/amazonstore') != 0
...although you may end up with some false positives depending how strict you are about the input and the values in your table.

You have the like backwards:
WHERE 'www.ebay.co.uk/amazonstore' like '%' + CompanyURL + '%'

Why not compare like this
SELECT *
FROM
dbo.Company
WHERE 'www.ebay.co.uk/amazonstore' LIKE '%'+ CompanyURL +'%' OR
CompanyURL LIKE '%www.ebay.co.uk/amazonstore%'

Related

How to fetch only a part of string

I have a column which has inconsistent data. The column named ID and it can have values such as
0897546321
ABC,0876455321
ABC,XYZ,0873647773
ABC,
99756
test only
The SQL query should fetch only Ids which are of 10 digit in length, should begin with a 08 , should be not null and should not contain all characters. And for those values, which have both digits and characters such as ABC,XYZ,0873647773, it should only fetch the 0873647773 . In these kind of values, nothing is fixed, in place of ABC, XYZ , it can be anything and can be of any length.
The column Id is of varchar type.
My try: I tried the following query
select id
from table
where id is not null
and id not like '%[^0-9]%'
and id like '[08]%[0-9]'
and len(id)=10
I am still not sure how should I deal with values like ABC,XYZ,0873647773
P.S - I have no control over the database. I can't change its values.
SQL Server generally has poor support regular expressions, but in this case a judicious use of PATINDEX is viable:
SELECT SUBSTRING(id, PATINDEX('%,08[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9],%', ',' + id + ','), 10) AS number
FROM yourTable
WHERE ',' + id + ',' LIKE '%,08[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9],%';
Demo
If you normalise your data, and split the delimited data into parts, you can achieve this some what more easily:
SELECT SS.value
FROM dbo.YourTable YT
CROSS APPLY STRING_SPLIT(YT.YourColumn,',') SS
WHERE LEN(SS.value) = 10
AND SS.value NOT LIKE '%[^0-9]%';
If you're on an older version of SQL Server, you'll have to use an alternative String Splitter method (such as a XML splitter or user defined inline table-value function); there are plenty of examples on these already on Stack Overflow.
db<>fiddle

SQL Server check if value is substring inside isnull

I have a field in UI interface that passes to a stored procedure a null value (when field is unfilled) or a contract number when it is filled. Substrings of the contract number are accepted as input.
Inside the procedure, I need to filter the results by this parameter.
I need something similar to this:
SELECT * FROM tableName tn
WHERE
tn.ContractNumber LIKE ISNULL('%' + #contractNumber + '%', tn.ContractNumber)
What do you think it is the best approach? Problem is that using a condition like this does not return values.
Simply:
SELECT *
FROM tableName tn
WHERE tn.ContractNumber LIKE '%' + #contractNumber + '%'
OR #contractNumber IS NULL
You are really checking multiple condition, so having them separated reads more intuitive (for most people, anyway).
I assume this is just a sample query, and you are not selecting * in reality...
Another one:
SELECT *
FROM tableName tn
WHERE tn.ContractNumber LIKE '%' + ISNULL(#contractNumber, '%') + '%'

What is the best way to return results similar to the input?

In my database I am selecting from a field containing Dillon Brookfield. I tried searching for brookfield with the following statement thinking LIKE would select the data, but it didn't work.
SELECT *
FROM [Reports]
WHERE ([VisitorName] LIKE '%' + #VisitorName + '%'
OR [PlateNumber] = #PlateNumber)
I record people who have been banned from a property along with their plate (if known), but if their name is not put in exactly it doesn't return the value. What would be the best way to return similar results?
This is more like a comment, but there is code inside and the comment only allows one #.
What data type is your #PlateNumber? Is it CHAR or VARCHAR? it can make a difference. Like these tests.
DECLARE #char NCHAR(20) = 'space';
SELECT '%'+#char+ '%',IIF('space' Like '%'+#char+ '%', 1,0);
DECLARE #varchar NVARCHAR(20) = 'space';
SELECT '%'+#varchar+ '%',IIF('space' Like '%'+#varchar+ '%', 1,0);
The first SELECT will give you
'%space %',0. -- there will be 15 blank character between space and %
The second SELECT will give you
'%space%', 1.
Create fulltext index. Search names/addresses and other similar fields with fulltext search - it'll be faster and you can find all names - Dillon Brookfield vs Brookfield Dillon.

Is it possible to search for multiple terms in a column by using a LIKE statement?

I'm trying to understand if the above question is possible. I've been conceptually thinking about it, and basically what I'm looking to do is:
Specify keywords that may appear in a title. Lets use the two terms "Portfolio" and "Mike"
I'm hoping to generate a query that will allow for me to search for when Portfolio is contained within a title, or Mike. These two titles need not to be together.
For instance, if I have a title dubbed: "Portfolio A" and another title "Mike's favorite" I'd like both of these titles to be returned.
The issue I've encountered with using a LIKE statement is the following:
WHERE 1=1
and rpt_title LIKE ''%'+#report_title+'%'''
If I were to input: 'Portfolio,Mike' it would search for the occurrence of just that within a title.
EDIT: I should have been a bit more clear. I believe it's necessary for me to input my variable as 'Portfolio, Mike' in order for it to find the multiple values. Is this possible?
I'm assuming you could maybe use a charindex with a substring and a replace?
Yep, multiple Like statements with OR will work just fine -- just make sure you use the correct parentheses:
SELECT ...
FROM ...
WHERE 1=1
and (rpt_title LIKE '%Portfolio%'
or rpt_title LIKE '%Mike%')
However, I might suggest you look into using a full-text search.
http://msdn.microsoft.com/en-us/library/ms142571.aspx
I can propose a solution where you could specify any number of masks, without using multiple LIKE -
DECLARE #temp TABLE (st VARCHAR(100))
INSERT INTO #temp (st)
VALUES ('Portfolio photo'),('- Mike'),('blank'),('else'),('est')
DECLARE #delims VARCHAR(30)
SELECT #delims = '|Portfolio|Mike|' -- %Portfolio% OR %Mike% OR etc.
SELECT t.st
FROM #temp t
CROSS JOIN (
SELECT substr =
SUBSTRING(
#delims,
number + 1,
CHARINDEX('|', #delims, number + 1) - number - 1)
FROM [master].dbo.spt_values n
WHERE [type] = N'P'
AND number <= LEN(#delims) - 1
AND SUBSTRING(#delims, number, 1) = '|'
) s
WHERE t.st LIKE '%' + s.substr + '%'

SQL startswith (using `LIKE`) on an expression

What's an appropriate way to do startswith(expression) in SQL?
I can do it with LIKE ((expression) || '%'), but it doesn't look very nice to me.
Full query is in form:
SELECT …, (SELECT COUNT(*)
FROM post AS child
WHERE child.path LIKE (post.path || '%')
AND child.depth >= post.depth)
FROM post WHERE …
I suppose it is preferable to use LIKE because of DB indexing for this case.
Just use LIKE 'input%'. I.E:
WHERE child.path LIKE post.path + '%'
(I assume this is for SQL Server, though this syntax probably works elsewhere)
In standard SQL, you can also say:
where position(post.path in child.path) = 1
I don't know if your RDBMS supports that. PostgreSQL does.
You can use
where DATE LIKE '[(SELECT STR(YEAR(GETDATE())-1))]%'
WHERE child.path LIKE '[(SELECT STR(YEAR(GETDATE())-1))]%' (post.path || '%')
WHERE CustomerName LIKE 'a%'
--Finds any values that start with "a"
WHERE CustomerName LIKE '%a'
--Finds any values that end with "a"
WHERE CustomerName LIKE '%or%'
--Finds any values that have "or" in any position
WHERE CustomerName LIKE '_r%'
--Finds any values that have "r" in the second position
WHERE CustomerName LIKE 'a__%'
--Finds any values that start with "a" and are at least 3 characters in length
WHERE ContactName LIKE 'a%o'
--Finds any values that start with "a" and ends with "o"
-- Case insensitive
2
SELECT * FROM my_table WHERE upper(my_column) LIKE 'SEARCHED %';
-- starts with
3
SELECT * FROM my_table WHERE upper(my_column) LIKE '% SEARCHED';
-- ends with
4
SELECT * FROM my_table WHERE upper(my_column) LIKE '%SEARCHED%'; -- contains