SQL Server 2008 - полнотекстовый поиск с несколькими ключевыми словами и разбиением на страницы - PullRequest
2 голосов
/ 15 октября 2011

Я не из базы данных (как покажет этот вопрос). Я пытаюсь написать табличную функцию, которую можно использовать с Linq To Sql в моем веб-приложении ASP.NET.

Скажем, я хочу найти книги, в которых заголовок или резюме могут содержать несколько ключевых слов (например, "история Австралии").

Я хочу отображать x результатов за раз, поэтому я должен быть в состоянии указать моей функции «пропустить» и «взять» определенное количество записей.

Некоторые книги могут быть помечены как «удаленные». Я не хочу их возвращать.

Вот что у меня есть:

CREATE FUNCTION SearchBooks
(
    @keywords nvarchar(50),
    @skip int,
    @take int
)
RETURNS TABLE
AS
RETURN
(
  SELECT TOP (@take)
         ROW_NUMBER() OVER (ORDER BY MyFTS.RANK DESC) AS RowID,
         MyFTS.RANK as Relevance,
         [ID],
         [Title],
         [Summary]
    FROM [Book]
    JOIN CONTAINSTABLE ([Book], ([Title], [Summary]), @keywords, @take) AS MyFTS ON MyFTS.[KEY] = [Book].[ID]
   WHERE ([Book].[Deleted] = 0) 
     AND (MyFTS.[RowID] BETWEEN (@skip + 1) AND (@skip + @take))
ORDER BY MyFTS.RANK DESC
)

Когда я пытаюсь создать эту функцию, SSMS выдает ошибку «Неверное имя столбца 'RowID'".

Полагаю, мне также нужно получить общее количество подходящих записей, чтобы я мог настроить нумерацию страниц?

Я надеюсь, что один из вас, гуру SQL, может указать мне правильное направление.

Ответы [ 2 ]

4 голосов
/ 15 октября 2011

Нельзя ссылаться на псевдоним столбца в предложении WHERE - используйте встроенное представление / производную таблицу:

  SELECT x.rowid,
         x.relevance,
         x.id,
         x.title,
         x.summary
   FROM (SELECT TOP (@take)
                ROW_NUMBER() OVER (ORDER BY MyFTS.RANK DESC) AS RowID,
                MyFTS.RANK as Relevance,
                [ID],
                [Title],
                [Summary]
           FROM [Book] b
           JOIN CONTAINSTABLE ([Book], ([Title], [Summary]), @keywords, @take) AS MyFTS ON MyFTS.[KEY] = b.id
          WHERE b.[Deleted] = 0) AS x
    WHERE x.[RowID] BETWEEN (@skip + 1) AND (@skip + @take))
ORDER BY x.relevance DESC
1 голос
/ 16 октября 2011

Спасибо OMG Ponies - это именно то, что я хотел.Я изменил функцию так, чтобы она также возвращала общее количество совпадающих строк (TotalRows), и теперь я должен иметь возможность разбивать на страницы.

CREATE FUNCTION SearchBooks
(
    @keywords nvarchar(50),
    @skip int,
    @take int
)
RETURNS TABLE
AS
RETURN
(
    SELECT TOP (@take) * FROM 
    (
        SELECT TOP (@take)
            ROW_NUMBER() OVER (ORDER BY MyFTS.RANK DESC) AS RowID,
            COUNT(*) OVER(PARTITION BY 1) as TotalRows,
            MyFTS.RANK as Relevance,
            [ID],
            [Title],
            [Summary]
        FROM [Book] b
        JOIN CONTAINSTABLE ([Book], ([Title], [Summary]), @keywords, @take) AS MyFTS ON MyFTS.[KEY] = b.[ID]
        WHERE b.[Deleted] = 0
    ) AS x
    WHERE x.[RowID] BETWEEN (@skip + 1) AND (@skip + @take)
    ORDER BY x.relevance DESC
)
...