3

我有一个表格显示基于数字的评分数字,如下所示:

  • 0-24 = 新手
  • 25-49 = 实习生
  • 50-74 = 中等
  • 75-99 = 专业
  • 100 = 超人

我需要取一个数值,并将其与上面最接近的等效等级相匹配。因此,80相当于Pro,因为它符合基本Pro级别,但低于基本超人级别。

我已经编写了一些代码来测试这一点,但 TOP 1 过滤器似乎在 JOIN 之前应用,这意味着我总是看到最低成绩而不是实际成绩。谁能帮我提出一个更好的选择?

SQL小提琴在这里

代码在这里:

DECLARE @tbl_levels TABLE ([schemeID] int, [calevel] numeric(5,2), [desc] nvarchar(200))
DECLARE @level numeric(5,2) = 70
DECLARE @schemeID int = 1

insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 0, 'Newbie')
insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 25, 'Trainee')
insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 50, 'Moderate')
insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 75, 'Pro')
insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 100, 'Superman')

SELECT
    *
FROM
    (SELECT
        @level as [level],
        @schemeID as [schemeID]) ca LEFT OUTER JOIN 
    (SELECT 
        TOP 1 * 
    FROM 
        @tbl_levels
    ORDER BY 
        calevel ASC
    ) lvl ON lvl.schemeID = ca.schemeID AND lvl.calevel <= ca.[level]
4

4 回答 4

2
SELECT @level as Level,s.*
from @tbl_levels s
where [calevel]=(Select Max([calevel]) from @tbl_levels where [calevel]<=@level)

作为对您评论的回答

SELECT
    t.[level],
    (Select [desc] from @tbl_levels where [calevel]=(Select Max([calevel]) from @tbl_levels where [calevel]<=t.[level])) as [Desc]
FROM
    @test t
于 2013-04-08T10:15:29.743 回答
2

您可以将问题改写为“与给定值匹配的最高级别是什么?” 然后解决方案变得明显。70 级为“中等”:

SELECT TOP(1) @level, *
FROM @tbl_levels
WHERE [calevel] <= @level
ORDER BY calevel DESC;

对于多个值,只需使用CROSS APPLY

SELECT
    t.[level],
    lvl.[desc]
FROM @test t 
cross apply (
select top(1) *
from @tbl_levels
where [calevel] <= [level]
order by calevel desc) as lvl;
于 2013-04-08T10:43:36.907 回答
1

(更新)尝试:

;with r as 
(select l.*, row_number() over (partition by [schemeID] order by [calevel]) rn
 from @tbl_levels l),
cte as
(select l.*, n.[calevel] as [nextlevel]
 from r l 
 left join r n on l.[schemeID] = n.[schemeID] and l.rn+1 = n.rn)
SELECT
    ca.*, cte.[calevel],cte.[nextlevel],cte.[desc]
FROM @test ca 
LEFT OUTER JOIN cte
ON ca.schemeID = cte.schemeID AND 
   ca.[level] >= cte.[calevel] AND
   ca.[level] < coalesce(cte.[nextlevel], ca.[level]+1)

(这里的 SQLFiddle )

于 2013-04-08T10:26:01.683 回答
0
DECLARE @tbl_levels TABLE ([schemeID] int, [calevel] numeric(5,2), [desc] nvarchar(200))
DECLARE @level numeric(5,2) = 70
DECLARE @schemeID int = 1

insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 0, 'Newbie')
insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 25, 'Trainee')
insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 50, 'Moderate')
insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 75, 'Pro')
insert into @tbl_levels ([schemeID],[calevel],[desc]) VALUES (1, 100, 'Superman')

SELECT
    TOP 1 *
FROM
    (SELECT
        @level as [level],
        @schemeID as [schemeID]) ca LEFT OUTER JOIN 
    (SELECT *
        FROM 
        @tbl_levels
    ) lvl ON lvl.schemeID = ca.schemeID AND lvl.calevel <= ca.[level]
    ORDER BY lvl.calevel DESC

拉吉

于 2013-04-08T10:12:03.227 回答