FreetextTable Query - sql-server

I have written an sql query to search 2 columns of a database, partNo and Description and it works fine for searching descriptions however if you search for a part number such as 164 it picks up all of the part numbers which start with 164 such as say: 164-20 but it doesn't pickup results like say APS164-20
here is my sql code, I am running mssql 2005.
SELECT FT_TBL.*, KEY_TBL.RANK
FROM Parts AS FT_TBL
INNER JOIN FREETEXTTABLE(Parts,(PartNo, Description),
'164') AS KEY_TBL
ON FT_TBL.PartNo = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC;
GO
I tried containstable but that didn't return the rows either

Full text search won't cover this scenario, where you're essentially looking for the search term as a substring within the text.
Try a traditional wildcard search instead:
SELECT *
FROM Parts AS FT_TBL
WHERE FT_TBL.PartNo like '%164%'

Related

SQL Server Full-Text-Index Search does not work

The full-text-index searches are not returning the expected results. The index is built by now, but not finding some really basic strings.
This query does not return the user called "Other 11".
SELECT KEY_TBL.RANK, FT_TBL.Firstname
FROM [user].[User] AS FT_TBL
INNER JOIN
CONTAINSTABLE([user].[User], Firstname,
'"Other*"') AS KEY_TBL
ON FT_TBL.UserId = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC
GO
If I rewrite the query like this, it will work and return the user called "Other 11".
SELECT KEY_TBL.RANK, FT_TBL.Firstname
FROM [user].[User] AS FT_TBL
INNER JOIN
CONTAINSTABLE([user].[User], Firstname,
'"Other 11"') AS KEY_TBL
ON FT_TBL.UserId = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC
GO
Something similar happens with FREETEXTTABLE and CONTAINS with a predicate search is also not working.
What could be the reason for this behavior?
Other and 11 are two differents words.
With a FTS predicate like '"Other*"' you will find "Otherwise" but never "Other 11"
You need to use a NEAR predicate like :
'NEAR((Other, 11),1, TRUE)'

SQL Server FTS indexing correct keywords but not returning results with those keywords

I've created a FTS catalog which indexes the Title column of a table called Articles. The word breaker language is set to Dutch.
The article title is "Contactgegevens Wijkteams 2019". My search term is 'contactgegevens' which is Dutch for 'Contact details'. This word could potentially be split into 'contact' and 'gegevens', although I have checked the indexed keywords which has successfully indexed the full word from the correct table/column.
Search term:
declare #searchTerm nvarchar(100)
select #searchTerm = 'contactgegevens';
Using Freetext:
If I use FREETEXT in the where clause I do find the result but it comes up near the end of around 300 rows. The majority of the rows don't have this word in the title column, not even words close in meaning.
SELECT a.ArticleID, a.Title
FROM Articles a
WHERE
FREETEXT(a.Title, #searchTerm))
Using FreeTextTable:
With FREETEXTTABLE, I get far less results but not one of them contain the keyword:'contactgegevens' or variations of it.
select *
from
freetexttable(Articles, Title, #search, LANGUAGE N'Dutch', 100) as key_table
inner join
Articles a on a.ArticleID = key_table.[Key]
order by
key_table.RANK desc
Using ContainsTable:
CONTAINSTABLE seems to return very similar results to FREETEXTTABLE.
SELECT key_table.rank, a.*
FROM Articles a
INNER JOIN
CONTAINSTABLE(Articles, Title, #searchTerm, LANGUAGE N'Dutch', 100) AS key_table on key_table.[KEY] = a.ArticleID
WHERE
ORDER BY
key_table.rank DESC
As mentioned I've checked the indexed keywords using the following query:
select *
from sys.dm_fts_index_keywords(DB_ID('MyDatabase'), OBJECT_ID('Articles'))
where (display_term like 'contactgegevens%') and column_id = 3
order by display_term
and the keyword is indexed for the correct table/column and looking at records close to this result I can see it's indexed other words relevant to the article title I'm looking for.
I'm expecting to be able to do a search for a phrase such as "Contactgegevens Wijkteams 2019" and have the article with that exact title appear at the top of the list, but it doesn't. In some cases it doesn't appear in the search results at all.
What am I missing here?
Turns out it was a simple mistake on my part. My join was using the ArticleID instead of the ArticleVersionID which is what the Catalog uses as its unique key and what is represented by key_table.[KEY].
SELECT key_table.rank, a.*
FROM Articles a
INNER JOIN
CONTAINSTABLE(Articles, Title, #searchTerm, LANGUAGE N'Dutch', 100) AS key_table on key_table.[KEY] = a.ArticleVersionID
WHERE
ORDER BY
key_table.rank DESC

SQL SERVER - FETCH NEXT ROWS returns duplicate results

I had a very weird issue in my website, and finally I succeeded to pinpoint the exact cause.
In my 'Entities' table I have several columns, such as "Id", "Title", "Date", "Indexing" and some more.
"Indexing" column indexed with full-text index.
Consider the following SQL query:
SELECT Id
FROM [dbo].[Entities] AS DocTable
INNER JOIN CONTAINSTABLE(Entities, Indexing, 'otherCriteria OR criteia') AS KEY_TBL
ON DocTable.Id = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC
This query works as expected and I getting around 600 results.
Now I adding pagination:
SELECT Id
FROM [dbo].[Entities] AS DocTable
INNER JOIN CONTAINSTABLE(Entities, Indexing, 'otherCriteria OR criteia') AS KEY_TBL
ON DocTable.Id = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC
OFFSET 50 ROWS FETCH NEXT 10 ROWS ONLY
No matter if I using OFFSET 30 or 40 or 50 -> I always getting exactly the same results!
Now the really weird part: if inside SELECT I asking to select 'Title' also (e.g. SELECT Id, Title) --> I getting correct results.
Any ideas?
OK, I think I got it
In Sql Server 2014 ORDER BY clause with OFFSET FETCH NEXT returns weird results
Says:
The ORDER BY clause contains a column or combination of columns that
are guaranteed to be unique.
Obviously, "RANK" is not unique. When I changed my query to:
SELECT Id
FROM [dbo].[Entities] AS DocTable
INNER JOIN CONTAINSTABLE(Entities, Indexing, 'otherCriteria OR criteia') AS KEY_TBL
ON DocTable.Id = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC, Id
OFFSET 50 ROWS FETCH NEXT 10 ROWS ONLY
I received correct results

Regarding sql server table column search with PATINDEX

i have never use PATINDEX() but i hard the table data can be search with PATINDEX().
often i got requirement to search multiple column of any table then i write the sql like
SELECT * FROM ADDRESS WHERE
((NAME LIKE 'Bill%') OR (CITY LIKE 'Bill%') OR (COMPANY LIKE 'Bill%'))
AND
((NAME LIKE 'Seattle%') OR (CITY LIKE 'Seattle%') OR (COMPANY LIKE 'Seattle%'))
so just tell me the above my sql performance will be good always? i search google to get better sql for searching multiple column of a table and found the below sql
select * from YourTable
WHERE PATINDEX('%text1%',COALESCE(field1,'') + '|' + COALESCE(field2,'') + '|'+ COALESCE(field3,'')+ '|' + COALESCE(field4,'')+ '|' + COALESCE(field9,''))>0
AND
PATINDEX('%text2%',COALESCE(field1,'') + '|' + COALESCE(field2,'') + '|'+ COALESCE(field3,'')+ '|' + COALESCE(field4,'')+ '|' +COALESCE(field9,''))>0
please guide me that the above sql PATINDEX syntax is ok for searching multiple column. if not then guide me how can i use the PATINDEX function to search multiple column with multiple value. thanks
UPDATE QS
you gave a link and that show me how to search multiple fields with multiple keyword. here it is
SELECT FT_TBL.ProductDescriptionID,
FT_TBL.Description,
KEY_TBL.RANK
FROM Production.ProductDescription AS FT_TBL INNER JOIN
CONTAINSTABLE (Production.ProductDescription,
Description,
'(light NEAR aluminum) OR
(lightweight NEAR aluminum)'
) AS KEY_TBL
ON FT_TBL.ProductDescriptionID = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEY_TBL.RANK DESC;
GO
but the problem is it is bit complicated to understand. can u give me sql for searching multiple fields with multiple keywords with full text search.
can i write something like this for searching multiple fields against multiple value
SELECT Title
FROM Production.Document
WHERE FREETEXT (Document, '(vital) OR (safety) OR (components)')
SELECT *
FROM YourTable
WHERE CONTAINS((ProductName, ProductNumber, Color),
'(vital) OR (safety) OR (components)');
what is the difference between FREETEXT and CONTAINS ?? can u please explain.
thanks
for fast search multiple columns you can setup Full-Text Search on sql server
then your queries will look like that
SELECT * FROM ADDRESS
WHERE Contains((name, city, company), 'Bill') and Contains(*, 'Seattle')
EDIT
Syntax of full-text search queries described here
EDIT
you can write
SELECT *
FROM YourTable
WHERE CONTAINS((ProductName, ProductNumber, Color),
'"vital" OR "safety" OR "components"');
rows that contains any of words in any searched column are returned. check this answer
for difference between contains and freetext check Sql Server Full-Text Search Protips Part 2: CONTAINS vs. FREETEXT article

FullText In Microsoft Sql Server - Returning exactly word

Can anyone tell me how to query a fulltext table in Sql Server, and get only exactly matches? Example:
I have those records in a table named "Items":
Bath
Bathroom
Test
Testing
I need to query for Bath and get only 1 record, "bath", excluding the word Bathroom. The same to the word "Test", wich in my context is different to "Testing".
Have you tried
SELECT column1, column2, ...
FROM [itens] AS FT_TBL INNER JOIN
CONTAINSTABLE([itens], *, 'Bath') AS KEY_TBL
ON FT_TBL.unique_key_column = KEY_TBL.[KEY]
http://msdn.microsoft.com/en-us/library/ms189760.aspx
or
SELECT columnname
FROM [itens]
WHERE CONTAINS(somecolumn, 'Bath')
http://msdn.microsoft.com/en-us/library/ms187787.aspx
Just noticed the updated questions (formatting applied).
If you column holds keywords (single word) then you could just select column = 'keyword'.
SELECT columnname
FROM [itens]
WHERE somecolumn = 'Bath'
are you searching for bath and test in one query or in different?
if in single, then one of the solutions i see is:
select top 1 from table where column like '[., ]bath[., ]%'
if in different, then union a series of such select's

Resources