基于查找表的 T-SQL (SQL Server 2012) 更新

And*_*ewS 5 sql-server t-sql sql-server-2012

我有以下与此问题相关的表格:

CREATE TABLE tblTitan(
titanId int IDENTITY (15483,1) PRIMARY KEY,
userId int UNIQUE NOT NULL,
titanName varchar(15) NOT NULL,
titanExperience int DEFAULT 0,
titanLevel int DEFAULT 1,
titanStep int DEFAULT 1,
titanBattleCount int DEFAULT 0,
titanWinCount int DEFAULT 0,
titanLossCount int DEFAULT 0,
titanDateCreated date DEFAULT GetDate(),
titanDateLegend date DEFAULT NULL,
titanNpcFlag bit DEFAULT 0,
titanActiveFlag bit DEFAULT 1,
titanImage varchar(150) DEFAULT 'basicTitan.png',
titanElementType int NOT NULL UNIQUE,
FOREIGN KEY (userId) REFERENCES tblUser (userId),
FOREIGN KEY (titanElementType) REFERENCES tblElement (elementId),
);

CREATE TABLE tblLevel(
levelId int IDENTITY (1,1) PRIMARY KEY,
levelNo int NOT NULL,
levelStep int NOT NULL,
levelExperienceMin int NOT NULL,
levelExperienceMax int NOT NULL,
);
Run Code Online (Sandbox Code Playgroud)

设想


泰坦与其他泰坦进行战斗,在此期间,算法会计算出获胜者,并且将 xp 奖励给泰坦。每次战斗后,我想检查泰坦的经验是否超过了 tblLevel 表中的阈值,该表是一个查找表。

tblLevel 具有如下值:

  • 级别 ID 1
    • 级别 1
    • levelStep 1
    • levelExperienceMin 0
    • 等级经验Max 100

  • 等级 2
    • 级别 1
    • levelStep 2
    • 等级经验最低 101
    • 等级经验Max 200

  • 等级 3
    • 第 2 级
    • levelStep 1
    • levelExperienceMin 201
    • 等级经验Max 300


使用 t-sql 代码,我如何根据 Titan 的经验更新 tblTitan 级别和步长值?例如:如果泰坦有 110 经验,我想按照 tblLevel 查找表的规定将titanLevel 和titanStep 值从(1, 1) 更新为(1, 2)。

我试过摆弄更新功能,但我不太确定如何使用子查询或其他方法来检查体验是否在最小和最大范围之间。

我的代码的一个示例尝试是:

UPDATE tblTitan t, tblLevel l
AS
SET t.titanStep = l.levelStep
WHERE t.titanExperience = >= l.levelExperienceMin AND <= l.levelExperienceMax
Run Code Online (Sandbox Code Playgroud)

这种命令在我的脑海中似乎很有意义,但在 T-SQL 中完全无效。如果有人可以帮助我编写代码或为我指明正确的方向,将不胜感激!

Jul*_*eur 2

我的第一个问题是:

SELECT您将如何编写具有类似模式的查询 ( )?

我可以看到该UPDATE声明有几个问题:

  • UPDATE2 张桌子(tblTitan t、tblLevel l)
  • 没有 FROM 子句
  • 旧的 JOIN 语法(TableA、TableB VS FROM TableA INNER JOIN TableB ON ...)
  • WHERE 子句中的表达式无效(缺失)(使用 < 和 > 运算符,例如 BETWEEN 运算符:A > B AND < C)

SELECT 语句如下所示:

SELECT titanId, titanName
    , t.titanLevel, t.titanStep
    , l.levelNo , l.levelStep
FROM @tblTitan t
INNER JOIN @tblLevel l
    ON t.titanExperience >= l.levelExperienceMin 
    AND t.titanExperience <= l.levelExperienceMax ;
Run Code Online (Sandbox Code Playgroud)
  • tblTitan t, tblLevel l 被适当的INNER JOIN子句替换
  • INNER JOIN 中的 WHERE 子句被 ON 子句替换
  • 无效的 BETWEEN like WHERE 子句被 2 个带有 < 和 > 的表达式替换

从这个有效的查询中,FROM ... JOIN ... WHERE可以保留该部分,并且可以用 anUPDATE t和 aSET子句替换 SELECT。

UPDATE语句可以这样写:

UPDATE t
    SET t.titanLevel = l.levelNo
        , t.titanStep = l.levelStep
FROM @tblTitan t
INNER JOIN @tblLevel l
    ON t.titanExperience >= l.levelExperienceMin 
    AND t.titanExperience <= l.levelExperienceMax 
-- WHERE titanId = ...;
Run Code Online (Sandbox Code Playgroud)

具有 3 个级别和 3 个泰坦的示例数据:

DECLARE @tblTitan TABLE (titanId int, titanName varchar(15) , titanExperience int, titanLevel int, titanStep int)
INSERT INTO @tblTitan(titanId, titanName, titanExperience, titanLevel, titanStep) VALUES
    (1, 'Bob', 110, 55, 66)
    , (2, 'Sam', 220, 77, 88)
    , (3, 'Isa', 50, 22, 33)

DECLARE @tblLevel TABLE(levelId int, levelNo int, levelStep int, levelExperienceMin int, levelExperienceMax int)
INSERT INTO @tblLevel(levelId, levelNo, levelStep, levelExperienceMin, levelExperienceMax) VALUES
    (1, 1, 1, 0, 100)
    , (2, 1, 2, 101, 200)
    , (3, 2, 1, 201, 300)
Run Code Online (Sandbox Code Playgroud)

UPDATE 之前 SELECT 的输出:

titanId | titanName | titanLevel    | titanStep | levelNo   | levelStep
3       | Isa       | 22            | 33        | 1         | 1
1       | Bob       | 55            | 66        | 1         | 2
2       | Sam       | 77            | 88        | 2         | 1
Run Code Online (Sandbox Code Playgroud)

UPDATE 后 SELECT 的输出:

titanId | titanName | titanLevel    | titanStep | levelNo   | levelStep
3       | Isa       | 1             | 1         | 1         | 1
1       | Bob       | 1             | 2         | 1         | 2
2       | Sam       | 2             | 1         | 2         | 1
Run Code Online (Sandbox Code Playgroud)