MySQL SELECT 或 INSERT 如果行尚不存在

MySQL SELECT or INSERT if row not exist yet

我有 3 个简单的 table:
玩家:
CREATE TABLE IF NOT EXISTS players (id INTEGER PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), UNIQUE KEY (name));

竞技场:
CREATE TABLE IF NOT EXISTS arenas (id INTEGER PRIMARY KEY AUTO_INCREMENT, name VARCHAR(40), UNIQUE KEY (name));

和积分:
CREATE TABLE IF NOT EXISTS points (playerID INTEGER, arenaID INTEGER, points INTEGER, PRIMARY KEY (playerID, arenaID));

我想向 points table 插入新行,并在需要时自动向玩家和竞技场插入行,目前我只有简单的插入:

INSERT INTO points (playerID, arenaID, points) 
VALUES 
(
    (SELECT players.id FROM players WHERE players.name LIKE ?),
    (SELECT arenas.id FROM arenas WHERE arenas.name LIKE ?),
    ?
) ON DUPLICATE KEY UPDATE points.points = LEAST(points.points, VALUES(points.points));

? 将替换为值。
热编辑这个 SQL,所以如果没有玩家 (SELECT players.id FROM players WHERE players.name LIKE ?) 那么它将向这个 table 插入新玩家,这与竞技场相同。
喜欢:(我的伪代码)

INSERT INTO points (playerID, arenaID, points) 
VALUES 
(
    (SELECT players.id FROM players WHERE players.name LIKE "Mary" ON KEY NOT EXIST INSERT INTO players (name) VALUES ("Mary")),
    (SELECT arenas.id FROM arenas WHERE arenas.name LIKE "BigBoy" ON KEY NOT EXIST INSERT INTO arenas (name) VALUES ("BigBoy")),
    200
) ON DUPLICATE KEY UPDATE points.points = LEAST(points.points, VALUES(points.points));

并且仍然插入新的 points 行。

为什么不分三步走,可以用存储过程

IF NOT EXISTS arenas (id INTEGER PRIMARY KEY AUTO_INCREMENT, name VARCHAR(40), UNIQUE KEY (name))
begin
    INSERT INTO arenas (name) VALUES ("BigBoy")
end
IF NOT EXISTS players (id INTEGER PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), UNIQUE KEY (name))
begin
    INSERT INTO players (name) VALUES ("Mary")
end

INSERT INTO points (playerID, arenaID, points) 
VALUES 
(
    (SELECT players.id FROM players WHERE players.name LIKE "Mary"),
    (SELECT arenas.id FROM arenas WHERE arenas.name LIKE "BigBoy"),
    200
) ON DUPLICATE KEY UPDATE points.points = LEAST(points.points, VALUES(points.points));

您可以使用 INSERT IGNORE 语句。

INSERT IGNORE INTO players (name) VALUES (?);

INSERT IGNORE INTO arenas (name) VALUES (?);

INSERT INTO points (playerID, arenaID, points) 
VALUES 
(
    (SELECT players.id FROM players WHERE players.name LIKE ?),
    (SELECT arenas.id FROM arenas WHERE arenas.name LIKE ?),
    ?
) ON DUPLICATE KEY UPDATE points.points = LEAST(points.points, VALUES(points.points));