Consider the following trials
table:
CREATE TABLE trials
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name_A VARCHAR(6),
name_B VARCHAR(6),
score_A INT,
score_B INT);
Abstractly, this represents a series of trials in which two possible things, A and B, are tried. A and B each get a score.
Later we add two columns winner
and loser
, both of the same datatype as name_A
and name_B
:
ALTER TABLE trials
ADD COLUMN winner VARCHAR(6),
ADD COLUMN loser VARCHAR(6);
For each trial, we want to fill in winner
with whichever name corresponds to the higher score.
For example, if a trial has
╔════════╦════════╦═════════╦═════════╗
║ name_A ║ name_B ║ score_A ║ score_B ║
╠════════╬════════╬═════════╬═════════╣
║ alice ║ bob ║ 10 ║ 5 ║
╚════════╩════════╩═════════╩═════════╝
then for that trial winner
should be alice
. Similarly, in this case loser
should be populated with bob
:
╔════════╦════════╦═════════╦═════════╦════════╦═══════╗
║ name_A ║ name_B ║ score_A ║ score_B ║ winner ║ loser ║
╠════════╬════════╬═════════╬═════════╬════════╬═══════╣
║ alice ║ bob ║ 10 ║ 5 ║ alice ║ bob ║
╚════════╩════════╩═════════╩═════════╩════════╩═══════╝
How does one UPDATE
to set the winner and loser columns in the trials
table properly?
Attempt:
I considered doing this with a sub-query. Here is a sub-query which find both the winners and losers:
SELECT id, name_A AS winner, name_B AS loser
FROM trials
WHERE score_A > score_B
UNION
SELECT id, name_B AS winner, name_A AS loser
FROM trials
WHERE score_B > score_A)
Trying to just get the winners, I did this:
UPDATE trials SET winner=(
SELECT id, winner from (
SELECT id, name_A AS winner
FROM trials
WHERE score_A > score_B
UNION
SELECT id, name_B AS winner
FROM trials
WHERE score_B > score_A) AS temp
)
WHERE temp.id = trials.id;
but it does not work because the field temp.id
is not recognized.
In such a case, you can use the following UPDATE statement syntax to update column from one table, based on value of another table. UPDATE first_table, second_table SET first_table. column1 = second_table. column2 WHERE first_table.id = second_table.
In this article, we will see, how to update from one table to another table based on ID match. We can update the table using UPDATE statement in SQL. The update statement is always followed by the SET command. The SET command is used to specify which columns and values need to be updated in a table.
You can update an entire row in one table with values from a row in another table.
You could make it without a subquery:
UPDATE test.trials AS t
SET t.winner=CASE WHEN t.score_A > t.score_B THEN t.name_A
WHEN t.score_A < t.score_B THEN t.name_B
ELSE NULL END,
t.loser=CASE WHEN t.score_A > t.score_B THEN t.name_B
WHEN t.score_A < t.score_B THEN t.name_A
ELSE NULL END;
Create table:
CREATE TABLE trials
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name_A VARCHAR(6),
name_B VARCHAR(6),
score_A INT,
score_B INT);
Empty table:
SELECT * FROM test.trials;
Test data:
INSERT INTO test.trials (id, name_A, name_B, score_A, score_B) VALUES ('1', 'alice', 'bob', '10', '5');
INSERT INTO test.trials (id, name_A, name_B, score_A, score_B) VALUES ('2', 'onare', 'some', '5', '11');
SELECT * FROM test.trials;
+----+--------+--------+---------+---------+
| id | name_A | name_B | score_A | score_B |
+----+--------+--------+---------+---------+
| 1 | alice | bob | 10 | 5 |
| 2 | onare | some | 5 | 11 |
+----+--------+--------+---------+---------+
Adding winner
and loser
columns:
ALTER TABLE test.trials
ADD COLUMN winner VARCHAR(10) NULL COMMENT '' AFTER score_B,
ADD COLUMN loser VARCHAR(10) NULL COMMENT '' AFTER winner;
SELECT * FROM test.trials;
+----+--------+--------+---------+---------+--------+-------+
| id | name_A | name_B | score_A | score_B | winner | loser |
+----+--------+--------+---------+---------+--------+-------+
| 1 | alice | bob | 10 | 5 | NULL | NULL |
| 2 | onare | some | 5 | 11 | NULL | NULL |
+----+--------+--------+---------+---------+--------+-------+
Running the query:
UPDATE test.trials AS t
SET t.winner=CASE WHEN t.score_A > t.score_B THEN t.name_A
WHEN t.score_A < t.score_B THEN t.name_B
ELSE NULL END,
t.loser=CASE WHEN t.score_A > t.score_B THEN t.name_B
WHEN t.score_A < t.score_B THEN t.name_A
ELSE NULL END;
SELECT * FROM test.trials;
+----+--------+--------+---------+---------+--------+-------+
| id | name_A | name_B | score_A | score_B | winner | loser |
+----+--------+--------+---------+---------+--------+-------+
| 1 | alice | bob | 10 | 5 | alice | bob |
| 2 | onare | some | 5 | 11 | some | onare |
+----+--------+--------+---------+---------+--------+-------+
You could make it even using IF
on winner
and loser
. I used CASE
because if there's a match between score_A
and score_B
, what do you want the query to do?. Add a new column match
.
UPDATE Trials
SET Winner =
CASE
WHEN score_A > score_B THEN name_A
WHEN score_B > score_A THEN name_B
ELSE NULL
END
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With