如何在全文搜索中使用CROSS APPLY的结果

时间:2017-11-13 16:32:45

标签: sql sql-server full-text-search cross-apply

我想在全文搜索(CROSS APPLYFREETEXT)中使用CONTAINS的结果,如下所示:

   SELECT  p.Id ,
            p.Name ,
            p.ShortDescription ,
            p.DisplayOrder ,
            cat.Name AS CategoryName
    FROM    dbo.Product AS p
            CROSS APPLY ( SELECT TOP 1
                                    c.Name ,
                                    c.Description ,
                                    c.Id
                          FROM      dbo.Product_Category_Mapping AS m
                                    LEFT JOIN dbo.Category AS c ON m.CategoryId = c.Id
                          WHERE     m.ProductId = p.Id
                                    AND c.Published = 1
                                    AND c.Deleted = 0
                        ) AS cat
    WHERE   p.Published = 1
            AND p.Deleted = 0
            AND ( CONTAINS ( p.NAME, @search )
                  OR CONTAINS ( p.FullDescription, @search )
                  OR CONTAINS ( cat.NAME, @search )
                );

我的问题是==> OR CONTAINS ( cat.Name, @search )。 SQL Server返回的错误是:

  

无法在“名称”列上使用CONTAINS或FREETEXT谓词,因为   它不是全文索引。

似乎CROSS APPLY的结果是一个表,并且该表不是全文索引的。如何将全文索引搜索条件应用于上面CROSS APPLY的结果?

1 个答案:

答案 0 :(得分:0)

尝试这样的事情:

SELECT  p.Id ,
            p.Name ,
            p.ShortDescription ,
            p.DisplayOrder ,
            cat.Name AS CategoryName
    FROM    dbo.Product AS p
            CROSS APPLY ( SELECT TOP 1
                                    c.Name ,
                                    c.Description ,
                                    c.Id
                          FROM      dbo.Product_Category_Mapping AS m
                                    LEFT JOIN dbo.Category AS c ON m.CategoryId = c.Id
                          WHERE     m.ProductId = p.Id
                                    AND c.Published = 1
                                    AND c.Deleted = 0
                        ) AS cat
    LEFT JOIN dbo.Category cat2 ON cat2.Id = cat.Id
    WHERE   p.Published = 1
            AND p.Deleted = 0
            AND ( CONTAINS ( p.NAME, @search )
                  OR CONTAINS ( p.FullDescription, @search )
                  OR CONTAINS ( cat2.NAME, @search )
                );

注意,我已在主要级别重新加入dbo.Category,并将CONTAINS谓词更改为引用cat2.NAME而非cat.NamecatCROSS JOIN别名,它确实不在全文索引之下,但在cat2下别名的主dbo.Category表在全文索引下,因此您可以使用其列{{ 1}}与NAME

此外,我认为如果您重新编写查询并在CONTAINS内移动CONTAINS支票会更好:

CROSS JOIN

HTH