patternsqlMinor
T-SQL (SQL Server 2012) Update based on lookup table
Viewed 0 times
update2012sqlbasedserverlookuptable
Problem
I have the following tables related to this question:
Scenario
A titan has battles with other titans, during which an algorithm calculates a winner, and xp is awarded to the titan. After each battle, I want to check if a titan's experience crosses a threshold from the tblLevel table, which is a lookup table.
tblLevel has values such as the following:
Question
Using t-sql code, how may I update the tblTitan level and step values based upon the experience the titan has? eg: if a titan has 110 experience, I want to update the titanLevel and titanStep values from (1, 1) to (1, 2), as dictated by the tblLevel lookup table.
I have tried fiddling around with the update function, but I am not too sure how to use a subquery or other method to be able to check if the experience is between the min and max ranges.
An example attempt of my code is:
```
UPDATE tblTitan t, tblLe
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,
);Scenario
A titan has battles with other titans, during which an algorithm calculates a winner, and xp is awarded to the titan. After each battle, I want to check if a titan's experience crosses a threshold from the tblLevel table, which is a lookup table.
tblLevel has values such as the following:
- levelId 1
- levelNo 1
- levelStep 1
- levelExperienceMin 0
- levelExperienceMax 100
- levelId 2
- levelNo 1
- levelStep 2
- levelExperienceMin 101
- levelExperienceMax 200
- levelId 3
- levelNo 2
- levelStep 1
- levelExperienceMin 201
- levelExperienceMax 300
Question
Using t-sql code, how may I update the tblTitan level and step values based upon the experience the titan has? eg: if a titan has 110 experience, I want to update the titanLevel and titanStep values from (1, 1) to (1, 2), as dictated by the tblLevel lookup table.
I have tried fiddling around with the update function, but I am not too sure how to use a subquery or other method to be able to check if the experience is between the min and max ranges.
An example attempt of my code is:
```
UPDATE tblTitan t, tblLe
Solution
My first question is:
How would you write a query (
I can see several problems with the
A SELECT statement would be like this:
From this valid query, the
The UPDATE statement can be writen like this:
Sample data with 3 levels and 3 titans:
Output of SELECT before UPDATE:
Output of SELECT after UPDATE:
How would you write a query (
SELECT) with a similar pattern?I can see several problems with the
UPDATE statement:UPDATEon 2 tables (tblTitan t, tblLevel l)
- No FROM clause
- Old JOIN syntax (TableA, TableB VS FROM TableA INNER JOIN TableB ON ...)
- Invalid (missing) expression in the WHERE clause (usage of operators like a BETWEEN operator: A > B AND
A SELECT statement would be like this:
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 ;- tblTitan t, tblLevel l is replaced by a proper
INNER JOINclause
- the WHERE clause is replaced by the ON clause in the INNER JOIN
- the invalid BETWEEN like WHERE clause is replace by 2 expresions with
From this valid query, the
FROM ... JOIN ... WHERE part can be kept and the SELECT can be replaced by an UPDATE t and a SET clauses.The UPDATE statement can be writen like this:
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 = ...;Sample data with 3 levels and 3 titans:
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)Output of SELECT before UPDATE:
titanId | titanName | titanLevel | titanStep | levelNo | levelStep
3 | Isa | 22 | 33 | 1 | 1
1 | Bob | 55 | 66 | 1 | 2
2 | Sam | 77 | 88 | 2 | 1Output of SELECT after UPDATE:
titanId | titanName | titanLevel | titanStep | levelNo | levelStep
3 | Isa | 1 | 1 | 1 | 1
1 | Bob | 1 | 2 | 1 | 2
2 | Sam | 2 | 1 | 2 | 1Code Snippets
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 ;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 = ...;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)titanId | titanName | titanLevel | titanStep | levelNo | levelStep
3 | Isa | 22 | 33 | 1 | 1
1 | Bob | 55 | 66 | 1 | 2
2 | Sam | 77 | 88 | 2 | 1titanId | titanName | titanLevel | titanStep | levelNo | levelStep
3 | Isa | 1 | 1 | 1 | 1
1 | Bob | 1 | 2 | 1 | 2
2 | Sam | 2 | 1 | 2 | 1Context
StackExchange Database Administrators Q#132499, answer score: 2
Revisions (0)
No revisions yet.