我有一个问题可以归结为这个简化版本: 我在Sql Server 2008中有一个这样的表(它是一个特定于我的搜索的非规范化表):
ItemId | CategoryId | Descr | ExtendedDescription
0001 | 1 | Mouse X | Blue mouse
0002 | 1 | Blue Pen | Beautiful ....
0003 | 2 | Blue Pencil | Pencil with ...
0004 | 2 | Eraser | Eraser with ....
我需要在此表中搜索单词(如“蓝色”),根据单词出现的位置为结果分配排名,并按排名对CategoryId进行分组。 我能做到这一点;当我尝试对结果进行分页时出现问题。 这是我尝试的存储过程(现在搜索的单词是固定的,但我知道如何使它成为参数;我也知道如何过滤ID以进行分页):
CREATE PROCEDURE [dbo].[spSearch]
AS
BEGIN
SET NOCOUNT ON;
SELECT
[CategoryId],
SUM(
CASE WHEN (PATINDEX('%Blue%', Descr) > 0) THEN 100 ELSE 0 END +
CASE WHEN (PATINDEX('%Blue%', ExtendedDescription) > 0) THEN 10 ELSE 0 END
) AS Ranking,
ROW_NUMBER() OVER(ORDER BY CategoryId DESC) ID
FROM [dbo].[Data]
where (Descr like '%Blue%' or
ExtendedDescription like '%Blue%')
GROUP BY CategoryId
ORDER BY Ranking DESC
END
使用此sp我得到以下结果:
CategoryId | Ranking | ID
0001 | 110 | 2
0002 | 100 | 1
问题是:为了对结果进行分页,我需要生成ID(ROW_NUMBER)以排序降序排名,而这样它就按CategoryId的顺序生成。 如果我尝试以这种方式改变sp:
ROW_NUMBER() OVER(ORDER BY Ranking DESC) ID
我无法保存sp,因为排名不是列。 你有一些提示吗?
答案 0 :(得分:1)
我认为使用Common Table expression
(CTE)我们可以解决这个问题
试试这个
;WITH cte AS
(
SELECT
[CategoryId],
SUM(
CASE WHEN (PATINDEX('%Blue%', Descr) > 0) THEN 100 ELSE 0 END +
CASE WHEN (PATINDEX('%Blue%', ExtendedDescription) > 0) THEN 10 ELSE 0 END
) AS Ranking,
ROW_NUMBER() OVER(ORDER BY CategoryId DESC) ID
FROM [dbo].[Data]
where (Descr like '%Blue%' or
ExtendedDescription like '%Blue%')
GROUP BY CategoryId
)
SELECT ROW_NUMBER () OVER(ORDER BY Ranking DESC) AS r_no,
Ranking,
ID
FROM cte