Sql Server Contains - sql

I need to match on a partial string but can't turn full-text indexing on so can't use contains. I've looked at Levenstein's function for determining the distance between two strings but I'm not looking for fuzzy matching but that every character in the column exists in the string.
I.e. If the string being passed is something like AB_SYS_20120430.TXT I want to match on any columns containing AB_SYS. The like predicate isn't getting me there. I really need the equivalent of the .NET contains feature but as mentioned turning on full text indexing isn't an option to be turned on. Thought I would see if there were any other possible work arounds.

Are you looking for the LIKE function?
http://www.w3schools.com/sql/sql_like.asp
... WHERE MyColumn LIKE '%AB_SYS%'
That may not be optimal, but it seems like it answers your question... If you can search from only the left or right side that could further optimize.
That is functionally similar to String.Contains
http://msdn.microsoft.com/en-us/library/dy85x1sa.aspx
EDIT: How will you parse the input text into the "relevant" substring?
EDIT: To search the same LIKE condition but reverse, from your partial column to the complete literal, simply append the wildcard characters:
... WHERE 'AB_SYS_20120430.TXT' LIKE '%' + MyColumn + '%'
EDIT: You have suggested that you can't get it to work. If you add the schema do your question then I can help you further but consider this:
You have a table called MyTable
In that table there is a column called MyColumn
Some rows in that table have the data 'AB_SYS' in MyColumn
Given the parameter 'AB_SYS_20120430.TXT' you want to return all matching rows
CREATE PROCEDURE MyTestProcedure
#pFullNameString nvarchar(4000) = '' -- parameter passed in, like AB_SYS_20120430.TXT
AS
BEGIN
SELECT
*
FROM
MyTable
WHERE
#pFullNameString LIKE '%' + MyTable.[MyColumn] + '%'
END
GO

You could use CHARINDEX
WHERE CHARINDEX(StringToCheckFor, StringToCheckIn) > 0

Related

Selection based on string containing one or many other strings

I have a table 'forms' with a column 'title'.
Inside my stored procedure I create a temp table '#temp1' with the column 'searchVals'.
Multiple strings are parsed into the stored procedure, the number of strings is variable.
What I'm trying to achieve is selecting a row if the 'title' contains one or many 'searchVal'. But I haven't been able to achieve this successfully yet.
For example something like this
SELECT title FROM #temp1 WHERE title IN ('%'+(SELECT searchVal FROM #temp1)+'%')
The issue is obviously that IN doesn't allow wildcards but if it did, this is the type of result I'm trying to achieve.
Stacking ORs also doesn't work as the number of rows in #temp1 is variable.
Predicate and free-text searches don't work as the forms database isn't indexed appropriately.
I've come up with what I think is a valid solution but I can't seem to construct it correctly. The function would be called from the WHERE clause and return a boolean. I'm sorry if this has been answered elsewhere, I did search extensively.
Below is my proposed solution with pseudocode code where I'm not sure of the interchangeable SQL code.
DECLARE FUNCTION dbo.checkVal(searchVal column, formTitle varchar)
RETURNS boolean
AS
BEGIN
WHILE (not end of column)
IF formTitle LIKE '%'+searchVal+'%'
RETURN true
END
END
RETURN FALSE
END
Sorry for my inconsistent and incorrect SQL code. I would appreciate any suggestions or corrections that would make my code work. Better solutions are welcome too.
Thank you.
How about to check every row of forms by an EXISTS()?
SELECT *
FROM forms f
WHERE EXISTS
(
SELECT *
FROM #temp1
WHERE f.title LIKE '%' + searchVals + '%'
)
You can use the LIKE operator in a JOIN statement:
SELECT DISTINCT f.*
FROM forms f
JOIN #temp1 t ON f.title LIKE '%' + t.column + '%'
But keep in mind that using the LIKE operator does come with a performance hit so you will want to reduce the number of rows in the forms table using a where clause if possible

SQL WHERE is anything

I'm working on a database query via a search bar and would like it to sometimes yield all results (depending on what is inputted)
I know that for SELECT you can use * in order to select all columns. Is there similar SQL syntax: i.e. WHERE name IS * to essentially always be true?
Edit to clarify:
The nature of the clause is that a variable is used to set the name (I'm actually not able to change the clause, that was made clear). i.e. WHERE name IS [[inputName]] (inputName is the decided by the search bar)
WHERE ISNULL(name, '') = ISNULL(name, '')
(assuming that 'name' is of a string type)
Just make the column reference itself. However, if this is the only goal of your query, why are you against omitting the WHERE clause?
If you want to return all results in a SQL statement, you can simply omit the WHERE clause:
SELECT <* or field names> FROM <table>;
You should use WHERE only when you want to filter your data on a certain field. In your case you just don't want to filter at all.
Actually you don't need WHERE clause at all in this situation. But if you insist then you should write your predicate so it always returns true. This can be done many ways:
Any predicate like:
WHERE 1=1
With column:
WHERE name = name OR name is null
With LIKE:
WHERE name LIKE '%' OR name is null
With passed parameter:
WHERE name = #name OR #name is null
You can think of more of course. But I think you need the last one. Pass NULL from app layer if you want all rows.

Finding the "&" character in SQL SERVER using a like statement and Wildcards

I need to find the '&' in a string.
SELECT * FROM TABLE WHERE FIELD LIKE ..&...
Things we have tried :
SELECT * FROM TABLE WHERE FIELD LIKE '&&&'
SELECT * FROM TABLE WHERE FIELD LIKE '&\&&'
SELECT * FROM TABLE WHERE FIELD LIKE '&|&&' escape '|'
SELECT * FROM TABLE WHERE FIELD LIKE '&[&]&'
None of these give any results in SQLServer.
Well some give all rows, some give none.
Similar questions that didn't work or were not specific enough.
Find the % character in a LIKE query
How to detect if a string contains special characters?
some old reference Server 2000
http://web.archive.org/web/20150519072547/http://sqlserver2000.databases.aspfaq.com:80/how-do-i-search-for-special-characters-e-g-in-sql-server.html
& isn't a wildcard in SQL, therefore no escaping is needed.
Use % around the value your looking for.
SELECT * FROM TABLE WHERE FIELD LIKE '%&%'
Your statement contains no wildcards, thus is equivalent to WHERE FIELD = '&'.
& isn't a special character in SQL so it doesn't need to be escaped. Just write
WHERE FIELD LIKE '%&%'
to search for entries that contain & somewhere in the field
Be aware though, that this will result in a full table scan as the server can't use any indexes. Had you typed WHERE FIELD LIKE '&%' the server could do a range seek to find all entries starting with &.
If you have a lot of data and can't add any more constraints, you should consider using SQL Server's full-text search to create and use and FTS index, with predicates like CONTAINS or FREETEXT

SQL Checking Substring in a String

I have a table with column mapping which store record: "IV=>0J,IV=>0Q,IV=>2,V=>0H,V=>0K,VI=>0R,VI=>1,"
What is the sql to check whether or not a substring is in column mapping.
so, I would like this:
if I have "IV=>0J" would return true, because IV=>0J is exact in string "mapping"
if I have "IV=>01" would return false. And so on...
I try this:
SELECT * FROM table WHERE charindex('IV=>0J',mapping)
But when I have "IV=>0", it returns TRUE. But, it should return FALSE.
Thank You..
You can search with commas included. Just also add one at beginning and end of mapping:
SELECT * FROM table WHERE charindex(',IV=>0J,',',' + mapping + ',') <> 0
or
SELECT * FROM table WHERE ',' + mapping + ',' LIKE '%,IV=>OJ,%'
This should do the trick:
SELECT * FROM table
WHERE
mapping LIKE '%,IV=>0J,%'
OR mapping LIKE '%,IV=>0J'
OR mapping LIKE 'IV=>0J,%'
OR mapping = 'IV=>0J'
But you should really normalize the database - you are currently violating the principle of atomicity, and therefore the 1NF. Your current difficulties in querying and the future difficulties with performance that you are about to encounter all stem from this root problem...
While you can search by including a comma in the string, this is a bad design for several reasons.
You are unable to take advantage of indexing
You force a full scan of the table, which will lead to bad performance AND excessive blocking.
You have to make sure that there is always a leading or a trailing comma (depends on what you expect in your LIKE expression).
You are no longer able to edit a single entry, you'll have to replace the entire string each time you want to change even a single mapping.
You open yourself to a concurrency nightmare if more that one users try to update different mappings that just happen to be stored in the same column.
Your table isn't even in 1st normal form any more, which is why you have such difficulties
You should normalize your mapping column, by extracting the data to a different mapping table, with at least the From and To columns you require. You can then add these columns to an index an convert your query using only a single index seek.
You can also add the ID values of your source table to the Mappings table and the index. This will allow you to convert the lookup for a source row to a join between the two tables that takes advantage of indexing
charindex returns the position of the text, not Boolean.
to check if the text exists, compare to 0:
SELECT * FROM table WHERE charindex('IV=>0J',mapping) <> 0
I think you're missing something here, the Charindex function does not return TRUE or FALSE.
It returns the starting point of the substring inside master string, or if the substring is not present, then -1.
So you query should read,
SELECT * FROM table WHERE charindex('IV=>0J',mapping) > 0

Use a LIKE statement on SQL Server XML Datatype

If you have a varchar field you can easily do SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%' to see if that column contains a certain string.
How do you do that for XML Type?
I have the following which returns only rows that have a 'Text' node but I need to search within that node
select * from WebPageContent where data.exist('/PageContent/Text') = 1
Yet another option is to cast the XML as nvarchar, and then search for the given string as if the XML vas a nvarchar field.
SELECT *
FROM Table
WHERE CAST(Column as nvarchar(max)) LIKE '%TEST%'
I love this solution as it is clean, easy to remember, hard to mess up, and can be used as a part of a where clause.
This might not be the best performing solution, so think twice before deplying it to production. It is however very usefull for a quick debug session, which is where I mostly use it.
EDIT: As Cliff mentions it, you could use:
...nvarchar if there's characters that don't convert to varchar
You should be able to do this quite easily:
SELECT *
FROM WebPageContent
WHERE data.value('(/PageContent/Text)[1]', 'varchar(100)') LIKE 'XYZ%'
The .value method gives you the actual value, and you can define that to be returned as a VARCHAR(), which you can then check with a LIKE statement.
Mind you, this isn't going to be awfully fast. So if you have certain fields in your XML that you need to inspect a lot, you could:
create a stored function which gets the XML and returns the value you're looking for as a VARCHAR()
define a new computed field on your table which calls this function, and make it a PERSISTED column
With this, you'd basically "extract" a certain portion of the XML into a computed field, make it persisted, and then you can search very efficiently on it (heck: you can even INDEX that field!).
Marc
Another option is to search the XML as a string by converting it to a string and then using LIKE. However as a computed column can't be part of a WHERE clause you need to wrap it in another SELECT like this:
SELECT * FROM
(SELECT *, CONVERT(varchar(MAX), [COLUMNA]) as [XMLDataString] FROM TABLE) x
WHERE [XMLDataString] like '%Test%'
This is what I am going to use based on marc_s answer:
SELECT
SUBSTRING(DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)'),PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')) - 20,999)
FROM WEBPAGECONTENT
WHERE COALESCE(PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')),0) > 0
Return a substring on the search where the search criteria exists