Test if a string contains at least 2 words in SQL - sql

I have an sql request like :
SELECT *
FROM table
WHERE lower(title) LIKE lower('%It's a beautiful string i think%')
I need to check if at least 2 words in my string It's a beautiful string i think are contained in my field title... How can i do that ?
For example, if in my field title i have the string I think it's beautiful, This query should return me this object...
Thanks !

You could split your string into a temporary table (say, using something like this: http://ole.michelsen.dk/blog/split-string-to-table-using-transact-sql/) and then do a join, with a count.

You could generate the following SQL statement dynamically:
SELECT title, count(*)
FROM
(
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% It %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% s %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% a %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% beautiful %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% string %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% I %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% think %')
) AS table2
GROUP BY title
HAVING COUNT(*) >= 2
A stored procedure might be more efficient and you could have the whole job done on the server side.

You could use a function like this
CREATE FUNCTION [dbo].[CheckSentece] (#mainSentence varchar(128), #checkSentence varchar(128))
RETURNS NUMERIC AS
BEGIN
SET #mainSentence=LOWER(#mainSentence)
SET #checkSentence=LOWER(#checkSentence)
DECLARE #pos INT
DECLARE #word varchar(32)
DECLARE #count NUMERIC
SET #count=0
WHILE CHARINDEX(' ', #checkSentence) > 0
BEGIN
SELECT #pos = CHARINDEX(' ', #checkSentence)
SELECT #word = SUBSTRING(#checkSentence, 1, #pos-1)
DECLARE #LEN NUMERIC
//Simple containment check, better to use another charindex loop to check each word from #mainSentence
SET #LEN=(SELECT LEN(REPLACE(#mainSentence,#word,'')))
if (#LEN<LEN(#mainSentence)) SET #count=#count+1
SELECT #checkSentence = SUBSTRING(#checkSentence, #pos+1, LEN(#checkSentence)-#pos)
END
return #count
END
and get the number of words from second sentence contained in the first one

Related

Write a query and pass the predefined value

First i write my query....
SELECT V.Country as Country, count(distinct MyNo) as CountData
FROM dbo.details V
WHERE country = 'india'
and (',' + ISNULL(replace(cateId,' ',''),'') + ',' like '%,31,%')
GROUP BY Country
I have a variable like #Id and want to replace like
(',' + ISNULL(replace(cateId,' ',''),'') + ',' like '%,#Id,%')
so any one help me how to do that and in ID i have the value in different record id now we assume is 31 so how to write that query
and thanks in advance.
like '%,' + cast(#Id as varchar(12)) + ',%'
If #Id is a varchar variable, you can omit the cast:
like '%,' + #Id + ',%'
You can also write this as:
(',' + ISNULL(replace(cateId, ' ', ''), '') + ',' like replace('%,#Id,%', '#Id', #id))

Extracting first word from a string in SQL, where the string is a single word

I am able to extract the first word from a string, using ANSI SQL, like this:
SELECT SUBSTRING(name FROM 1 FOR POSITION(' ' IN name)) AS first_name
However, if the original string is only one word long (ie, if there is no space), it returns an empty substring.
How can the above query be adapted to solve this problem?
Thanks in advance.
I'm sure there is a cleaner way to do it, but this works.
DECLARE #tbl TABLE (i varchar(100));
INSERT INTO #tbl ( i )
VALUES ('hello'), ('hello space here');
SELECT *,
SUBSTRING(i, 0, CASE CHARINDEX(' ', i)
WHEN 0 THEN LEN(i) + 1
ELSE CHARINDEX(' ', i)
END)
FROM #tbl
Simply but messy solution - add a space on the end:
SELECT SUBSTRING((name || ' ') FROM 1 FOR POSITION(' ' IN (name || ' '))) AS first_name
Use a conditional if statement.
For a MySQL/SQL Server answer:
SELECT IF(INSTR(name, ' ') >0, LEFT(name, INSTR(name, ' ') - 1), name) AS firstname
For Oracle:
SELECT IF(INSTRB(name, ' ', 1, 1) >0, SUBSTR(name, 1, INSTRB(name, ' ', 1, 1) - 1), name) AS firstname
I personally prefer the Regexp query for this, but below query also works.
You basically append a space at the end of the string and search for the position of the space using INSTR.
ORACLE:
select substr(Var1, 0,INSTR(Var1||' ',' ')) from table-name;
Replace Var1 with the column-name or string you are evaluating.
Put Column Name in place of #foo
DECLARE #Foo VARCHAR(50) = 'One Two Three'
SELECT
CASE
--For One Word
WHEN CHARINDEX(' ', #Foo, 1) = 0 THEN #Foo
--For multi word
ELSE SUBSTRING(#Foo, 1, CHARINDEX(' ', #Foo, 1) - 1)
END
DECLARE #test VARCHAR(50) = 'One Two Three'
SELECT SUBSTRING(LTRIM(#test),1,(CHARINDEX(' ',LTRIM(#test) + ' ')-1))
you can use this to get the first word of a string.initcap
will get you the first letter capital.
SELECT SUBSTR(column_1, 1, INSTR(column_1, ' ', 1,1) ) FROM table_name WHERE column_1= initcap('your string');

Query with LIKE statement for any of the words, not whole

SELECT *
FROM Products
WHERE Name LIKE '%' +
(SELECT TOP 1 Gift.Name FROM Gift WHERE Id = 65)
+ '%'
Subquery returns sth like "toy gun". Some of them even consists of three or more words. Obviously main query looks for Names that include "toy gun".
What I want to do is return all results for "toy" or "gun".
Any suggestion?
You will need to create function that splits out the text of your column. Here is one possible way to do it:
http://www.sqlservercentral.com/blogs/querying-microsoft-sql-server/2013/09/19/how-to-split-a-string-by-delimited-char-in-sql-server/
Once you have that, you can use a JOIN with a LIKE:
SELECT
*
FROM
Products p
INNER JOIN dbo.fnSplitString
(
SELECT TOP 1 Gift.Name FROM Gift WHERE Id = 65
) sub ON p.Name LIKE '%' + sub.splitdata + '%'
(I'm sure that's not 100% correct syntax.)
If you have Full Text indexing enabled then using FREETEXT query produce what you want. You can check Full Text if it enabled by running the below query:
SELECT FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')
If the above returns 1, then your good to go. If 0 is returned then search for installation instructions for your SQL Server version. Here is a good guide to setting up the FullText index http://blog.sqlauthority.com/2008/09/05/sql-server-creating-full-text-catalog-and-index/.
Once set up you can use the below code to perform your required search:
Declare #searchString nvarchar (100);
Select top 1 #searchString = Gift.Name FROM Gift WHERE Id=65;
Select * From Products Where FREETEXT (Name, #searchString);
declare #query varchar(8000)
select #query='
SELECT *
FROM Products
WHERE Name LIKE ''%' +
replace((SELECT TOP 1 Gift.name FROM Gift),' ','%'' or name like ''%')
+ '%'''
exec (#query)
Use a split function on Gift.name, to generate a table of single-word names, and link to that table on Product.Name LIKE '%'+SplitFunctionTable.Name+'%'.
If you don't already have a split function in your database, Google can show you some.
This chops a string of two words delimited by one space into single words
declare #s nvarchar (30)='toy gun'
select LTRIM(SUBSTRING(#s, CHARINDEX(' ',#s)+1,len(#s)))
select LTRIM(SUBSTRING(#s, 0,CHARINDEX(' ',#s)+1))
Maybe this helps. Looks ugly though from any angle...
SELECT *
FROM Products
WHERE Name LIKE '%' +
(SELECT TOP 1 Gift.Name FROM Gift WHERE Id = 65)
+ '%'
I'm not sure if that's what you want, but if you don't want to create function.
SELECT *
FROM Products
WHERE ' ' + (SELECT TOP 1 Gift.Name FROM Gift WHERE Id = 65) + ' '
LIKE '%' + ' ' + REPLACE(REPLACE(REPLACE(
Name,'[','[[]'), '_', '[_]'), '%', '[%]') + ' ' + '%'
.
Gift.Name Products.Name
' toy gun ' LIKE '% toy %' true
' toy gun ' LIKE '% gun %' true
' toy gun ' LIKE '% toy gun %' true
' toy gun ' LIKE '% guns %' false
' toy gun ' LIKE '% gu %' false
' toy gun ' LIKE '% to %' false
' toy gun ' LIKE '% toys %' false
' toy gun ' LIKE '% gun toy %' false

Query display names

I have a 2 columns in a SQL Server table.
One is characters like 'Attn: firstname lastname', and the other column has a number associated with that person.
I can't figure out how to query them so the info comes out as:
Lastname, Firstname - number
If you are in SQL Server you can do this
Select Col1 + ' - ' + Col2
From dbo.{Table}
Where {Conditions}
If you mean you need to drop the "attn:" you can do something like this
Select substring(Col1, 5,len(Col1)-5) + ' - ' + Col2
From dbo.{Table}
Where {Conditions}
Instead of hardcoding the index of ':', you can do something like this
SELECT REPLACE(RIGHT(Col1, (LEN(Col1) - CHARINDEX(':', Col1)-1)),' ',', ') + ' - ' + Col2
To test this you can run the following
DECLARE #column1string AS VARCHAR(30), #column2number AS VARCHAR(10)
SET #column1string = 'Attn: Firstname Lastname'
SET #column2number = '12345678'
SELECT REPLACE(RIGHT(#column1string, (LEN(#column1string) - CHARINDEX(':', #column1string)-1)),' ',', ') + ' - ' + #column2number

SQL method to replace repeating blanks with single blanks

Is there a more elegant way of doing this. I want to replace repeating blanks with single blanks....
declare #i int
set #i=0
while #i <= 20
begin
update myTable
set myTextColumn = replace(myTextColumn, ' ', ' ')
set #i=#i+1
end
(its sql server 2000 - but I would prefer generic SQL)
This works:
UPDATE myTable
SET myTextColumn =
REPLACE(
REPLACE(
REPLACE(myTextColumn
,' ',' '+CHAR(1)) -- CHAR(1) is unlikely to appear
,CHAR(1)+' ','')
,CHAR(1),'')
WHERE myTextColumn LIKE '% %'
Entirely set-based; no loops.
So we replace any two spaces with an unusual character and a space. If we call the unusual character X, 5 spaces become: ' X X ' and 6 spaces become ' X X X'. Then we replace 'X ' with the empty string. So 5 spaces become ' ' and 6 spaces become ' X'. Then, in case there was an even number of spaces, we remove any remaining 'X's, leaving a single space.
Here is a simple set based way that will collapse multiple spaces into a single space by applying three replaces.
DECLARE #myTable TABLE (myTextColumn VARCHAR(50))
INSERT INTO #myTable VALUES ('0Space')
INSERT INTO #myTable VALUES (' 1 Spaces 1 Spaces. ')
INSERT INTO #myTable VALUES (' 2 Spaces 2 Spaces. ')
INSERT INTO #myTable VALUES (' 3 Spaces 3 Spaces. ')
INSERT INTO #myTable VALUES (' 4 Spaces 4 Spaces. ')
INSERT INTO #myTable VALUES (' 5 Spaces 5 Spaces. ')
INSERT INTO #myTable VALUES (' 6 Spaces 6 Spaces. ')
select replace(
replace(
replace(
LTrim(RTrim(myTextColumn)), ---Trim the field
' ',' |'), ---Mark double spaces
'| ',''), ---Delete double spaces offset by 1
'|','') ---Tidy up
AS SingleSpaceTextColumn
from #myTable
Your Update statement can now be set based:
update #myTable
set myTextColumn = replace(
replace(
replace(
LTrim(RTrim(myTextColumn)),
' ',' |'),
'| ',''),
'|','')
Use an appropriate Where clause to limit the Update to only the rows that have you need to update or maybe have double spaces.
Example:
where 1<=Patindex('% %', myTextColumn)
I have found an external write up on this method: REPLACE Multiple Spaces with One
select
string = replace(
replace(
replace(' select single spaces',' ','<>')
,'><','')
,'<>',' ')
Replace duplicate spaces with a single space in T-SQL
SELECT 'starting...' --sets ##rowcount
WHILE ##rowcount <> 0
update myTable
set myTextColumn = replace(myTextColumn, ' ', ' ')
where myTextColumn like '% %'
Not very SET Based but a simple WHILE would do the trick.
CREATE TABLE #myTable (myTextColumn VARCHAR(32))
INSERT INTO #myTable VALUES ('NoSpace')
INSERT INTO #myTable VALUES ('One Space')
INSERT INTO #myTable VALUES ('Two Spaces')
INSERT INTO #myTable VALUES ('Multiple Spaces .')
WHILE EXISTS (SELECT * FROM #myTable WHERE myTextColumn LIKE '% %')
UPDATE #myTable
SET myTextColumn = REPLACE(myTextColumn, ' ', ' ')
WHERE myTextColumn LIKE '% %'
SELECT * FROM #myTable
DROP TABLE #myTable
Step through the characters one by one, and maintain a record of the previous character. If the current character is a space, and the last character is a space, stuff it.
CREATE FUNCTION [dbo].[fnRemoveExtraSpaces] (#Number AS varchar(1000))
Returns Varchar(1000)
As
Begin
Declare #n int -- Length of counter
Declare #old char(1)
Set #n = 1
--Begin Loop of field value
While #n <=Len (#Number)
BEGIN
If Substring(#Number, #n, 1) = ' ' AND #old = ' '
BEGIN
Select #Number = Stuff( #Number , #n , 1 , '' )
END
Else
BEGIN
SET #old = Substring(#Number, #n, 1)
Set #n = #n + 1
END
END
Return #number
END
GO
select [dbo].[fnRemoveExtraSpaces]('xxx xxx xxx xxx')
Here is a Simplest solution :)
update myTable
set myTextColumn = replace(replace(replace(LTrim(RTrim(myTextColumn )),' ','<>'),'><',''),'<>',' ')
create table blank(
field_blank char(100))
insert into blank values('yyy yyyy')
insert into blank values('xxxx xxxx')
insert into blank values ('xxx xxx')
insert into blank values ('zzzzzz zzzzz')
update blank
set field_blank = substring(field_blank,1,charindex(' ',field_blank)-1) + ' ' + ltrim(substring(field_blank,charindex(' ',field_blank) + 1,len(field_blank)))
where CHARINDEX (' ' , rtrim(field_blank)) > 1
select * from blank
For me the above examples almost did a trick but I needed something that was more stable and independent of the table or column or a set number of iterations. So this is my modification from most of the above queries.
CREATE FUNCTION udfReplaceAll
(
#OriginalText NVARCHAR(MAX),
#OldText NVARCHAR(MAX),
#NewText NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
WHILE (#OriginalText LIKE '%' + #OldText + '%')
BEGIN
SET #OriginalText = REPLACE(#OriginalText,#OldText,#NewText)
END
RETURN #OriginalText
END
GO
Lets say, your Data like this
Table name : userdata Field: id, comment, status,
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br>
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br>
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br>
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br>
So just do like this
update userdata set comment=REPLACE(REPLACE(comment," ","-SPACEHERE-"),"-SPACEHERE"," ");
I didn't tested , but i think this will work.
Try this:
UPDATE Ships
SET name = REPLACE(REPLACE(REPLACE(name, ' ', ' ' + CHAR(1)), CHAR(1) + ' ', ''), CHAR(1), '')
WHERE name LIKE '% %'
REPLACE(REPLACE(REPLACE(myTextColumn,' ',' %'),'% ',''),'%','')
Statement above worked terrifically for replacing multiple spaces with a single space. Optionally add LTRIM and RTRIM to remove spaces at the beginning.
Got it from here: http://burnignorance.com/database-tips-and-tricks/remove-multiple-spaces-from-a-string-using-sql-server/
WHILE
(SELECT count(myIDcolumn)
from myTable where myTextColumn like '% %') > 0
BEGIN
UPDATE myTable
SET myTextColumn = REPLACE(myTextColumn ,' ',' ')
END
Try it:
CREATE OR REPLACE FUNCTION REM_SPACES (TEXTO VARCHAR(2000))
RETURNS VARCHAR(2000)
LANGUAGE SQL
READS SQL DATA
BEGIN
SET TEXTO = UPPER(LTRIM(RTRIM(TEXTO)));
WHILE LOCATE(' ',TEXTO,1) >= 1 DO
SET TEXTO = REPLACE(TEXTO,' ',' ');
END WHILE;
RETURN TEXTO;
END
Update myTable set myTextColumn = replace(myTextColumn, ' ', ' ');
The above query will remove all the double blank spaces with single blank space
But this would work only once.