我会这样改变Level_Points
表格:
ALTER TABLE Level_Points
ADD max_points INT NOT NULL;
ALTER TABLE Level_Points
ADD CONSTRAINT CK_LevelPoints_VerifyPoints CHECK(points < max_points);
在这种情况下,points
列将存储最小数量。点数和max_points
列数将存储最大数量。当前级别所需的点数。接下来,我必须确保这个级别是连续的,它们没有重叠并且没有间隙(但这些限制超出了此答案的目的:请参阅Alexander Kuznetsov 撰写的这篇文章)。此外,还需要一些索引:
CREATE UNIQUE INDEX IUN_LevelPoints_points
ON Level_Points(points);
CREATE UNIQUE INDEX IUN_LevelPoints_points_maxpoints
ON Level_Points(points, max_points); -- This index is useful because the final query needs both columns: points and max_points; in SQL Server, max_points column can be covered column: ... ON Level_Points(points) INCLUDE (max_points), then the first index (IUN_LevelPoints_points) is no more needed
存储在此表中的一些示例行:
INSERT INTO Level_Points ("level", "points", "max_points") VALUES (0, 0, 5); -- level 0 for players which have less than 5 points
INSERT INTO Level_Points ("level", "points", "max_points") VALUES (1, 5, 10);
INSERT INTO Level_Points ("level", "points", "max_points") VALUES (2, 10, 15);
INSERT INTO Level_Points ("level", "points", "max_points") VALUES (3, 15, 100);
INSERT INTO Level_Points ("level", "points", "max_points") VALUES (4, 100,2147483647); -- 2147483647 is the maximum value for a INT in SQL Server
在这种情况下,最终查询只是一个简单的左/内连接:
SELECT ..., lvl.level
FROM accounts AS acc LEFT JOIN Level_Points AS lvl
ON acc.points >= lvl.points
AND acc.points < lvl.max_points