Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
DB Engine
SQL ServerMSDESQL Server CE
Services
Analysis (Data Mining)Analysis (OLAP)DTSIntegration ServicesNotification ServicesReporting Services
Programming
CLRConnectivitySQLXML
Other Technologies
ClusteringEnglish QueryFull-Text SearchReplicationService Broker
General
Data WarehousingPerformanceSecuritySetupSQL Server ToolsOther SQL Server Topics
DirectoryUser Groups
Related Topics
MS AccessOther DB ProductsMS Server Products.NET DevelopmentVB DevelopmentJava DevelopmentMore Topics ...

SQL Server Forum / Other Technologies / Full-Text Search / May 2008

Tip: Looking for answers? Try searching our database.

Best scenario for FREETEXTTABLE

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
nospam@please.net - 19 May 2008 07:07 GMT
Hi,
I'm having some difficulties as to which approach is the right one in
this scenario:

I have a table of books (tblShopItem), a table of categories (authors,
series etc. = tblShopCategory) and a table that connects these
(tblShop_Item_Category_Ref), so one book can have multiple authors,
series etc.
When I recieve the data, I recieve the list of categories (and
category types) for one book via a UDF as a comma-delimited list, so I
only get one line per book in the resultset.
My problem is that I can't use FREETEXT or FREETEXTTABLE properly in
this context, because I want to search both the Book-table and the
Category-table, so I find books that matches one or the other instead
of books that matches the criteria in BOTH tables!
Also, the @SearchString paramter should be optional which I don't know
how to do when using JOINs. I've tried to create a view of the SELECT-
statement, but are not allowed to create a unique index because of the
UDF - But maybe my approach is wrong - any suggestions would be
appreciated!
Best,
Mazzo

Here's the code:

ALTER PROCEDURE [dbo].[usp_SearchAll] (
@PageIndex int,
@PageSize int,
@SearchString nvarchar(255) = NULL,
@CategoryID int = NULL
)
AS
SET NOCOUNT ON;

WITH SearchTable AS
(
SELECT ROW_NUMBER() OVER (ORDER BY si.ItemName) AS ROW,
si.ID, si.tblShopProductType_ID, si.ItemName, si.ShortDescription,
si.Issue, si.Price, si.CampaignPrice, si.CampaignStartDate,
si.CampaignEndDate, sir.Rating, dbo.GetCategories(si.id) AS Categories
FROM tblShopItem si

JOIN tblShopItem_Category_Ref scr ON scr.tblShopItem_ID = si.ID
LEFT JOIN tblShopItemReview sir ON sir.tblShopItem_ID = si.ID

JOIN FREETEXTTABLE(tblShopCategory, *, @SearchString) AS tblKeyShopCat
ON scr.tblShopCategory_ID = tblKeyShopCat.[KEY]
--JOIN FREETEXTTABLE(tblShopItem, *, @SearchString) AS tblKeyShopItem
ON si.ID = tblKeyShopItem.[KEY]

WHERE scr.tblShopCategory_ID = COALESCE(@CategoryID,
scr.tblShopCategory_ID)
AND GetDate() BETWEEN si.StartDate AND si.EndDate
)
SELECT SearchTable.*, (SELECT MAX(ROW) FROM SearchTable) AS RC FROM
SearchTable
WHERE ROW BETWEEN (@PageIndex - 1) * @PageSize + 1 AND @PageIndex *
@PageSize

SET NOCOUNT OFF
nospam@please.net - 19 May 2008 08:45 GMT
Matijah wrote:
You can create an indexed view referencing both tables (without the
UDF) and
create a full-text index on the view rather than the tables.

Thanks for your reply. The above solution will provide double unique
id's for the books that have more than one author. I tried to create a
combined unique identity with the keys from both the books and the
authors-table, but wasn't allowed to full-text-index it.
Best,
Mazzo
ML - 19 May 2008 09:19 GMT
Yes, composite indexes are not supported by the full-text index.

Can you post table DDL and sample data?

Also, consider using a subquery to restrict the set returned by one of the
tables, and then join the other table to the subquery result.

ML

---
Matija Lah, SQL Server MVP
http://milambda.blogspot.com/
nospam@please.net - 19 May 2008 10:00 GMT
Hi,
I added an extra ID field to the one-to-many table,
"tblShopItem_Category_Ref":

ID (PK, auto increment)
tblShopItem_ID
tblCategory_ID

- Then I created a view with this new key as the unique id:

CREATE VIEW viewAll WITH SCHEMABINDING AS
SELECT si.ID, si.tblShopProductType_ID, si.ItemName,
si.ShortDescription, si.Issue, si.Price, si.CampaignPrice,
si.CampaignStartDate, si.CampaignEndDate, scr.ID AS idxID, sc.ID AS
catID, sc.Category
FROM dbo.tblShopItem si
JOIN dbo.tblShopItem_Category_Ref scr ON scr.tblShopItem_ID = si.ID
JOIN dbo.tblShopCategory sc ON sc.ID = scr.tblShopCategory_ID
GO
CREATE UNIQUE CLUSTERED INDEX pk_viewAll ON viewAll (idxID)

- And the sproc was changed to this:

ALTER PROCEDURE [dbo].[usp_SearchAll] (
@PageIndex int,
@PageSize int,
@SearchString nvarchar(255) = NULL,
@CategoryID int = NULL
)
AS
SET NOCOUNT ON;

WITH SearchTable AS
(
 SELECT ROW_NUMBER() OVER (ORDER BY va.ItemName) AS ROW,
 va.ID, va.tblShopProductType_ID, va.ItemName, va.ShortDescription,
va.Issue, va.Price, va.CampaignPrice, va.CampaignStartDate,
va.CampaignEndDate, sir.Rating, dbo.GetCategories(va.id) AS Categories
 FROM viewAll va
 LEFT JOIN tblShopItemReview sir ON sir.tblShopItem_ID = va.ID
 JOIN FREETEXTTABLE(viewAll, *, @SearchString) AS tblKey ON va.idxID
= tblKey.[KEY]
 WHERE GetDate() BETWEEN va.StartDate AND va.EndDate
)
SELECT SearchTable.*, (SELECT MAX(ROW) FROM SearchTable) AS RC FROM
SearchTable
WHERE ROW BETWEEN (@PageIndex - 1) * @PageSize + 1 AND @PageIndex *
@PageSize

SET NOCOUNT OFF

- And it works very well! Becase I'm using ROW_NUMBER I still get
dublicate records - I figure if I didn't use ROW_NUMBER and added
DISTINCT to the SELECT I wouldn't! Also, I'd like to add the optional
search option for @CategoryID, like this:

AND va.catID = COALESCE(@CategoryID, va.catID)

- But because the JOIN with FREETEXTTABLE requires a @SearchString-
parameter, I can't leave that empty. Maybe it's better to put this in
it's own sproc?!
Best,
Mazzo
ML - 19 May 2008 10:22 GMT
> - And it works very well! Becase I'm using ROW_NUMBER I still get
> dublicate records - I figure if I didn't use ROW_NUMBER and added
> DISTINCT to the SELECT I wouldn't!

Consider eliminating duplicates without using DISTINCT, but rather by
properly restricting the result set (e.g. using the WHERE clause).

> Also, I'd like to add the optional search option for @CategoryID...

I can't see why you couldn't add that restriction.

> - But because the JOIN with FREETEXTTABLE requires a @SearchString-
> parameter, I can't leave that empty. Maybe it's better to put this in
> it's own sproc?!

Assuming you want to return all rows if @SearchString is null:

if @SearchString is null
 begin
   -- select without freetexttable
 end
else
 begin
   -- select with freetexttable
 end


ML

---
Matija Lah, SQL Server MVP
http://milambda.blogspot.com/
nospam@please.net - 19 May 2008 11:05 GMT
Ah, of course - sometimes the solution is so simple you miss it!
Thanks so much for your reply.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.