更新...根据条件从不同的列

时间:2018-03-06 12:09:27

标签: sql postgresql sql-update

我为我的问题准备了一个简单的SQL Fiddle

在PostgreSQL 10中,用户ID存储在words_users表中,但它们的名称存储在words_social表中:

CREATE TABLE words_users (
        uid     SERIAL PRIMARY KEY
);

CREATE TABLE words_social (
        sid     text     NOT NULL,
        social  integer  NOT NULL CHECK (0 < social AND social <= 64),
        given   text     NOT NULL CHECK (given ~ '\S'),
        uid     integer  NOT NULL REFERENCES words_users ON DELETE CASCADE,
        PRIMARY KEY(sid, social)
);

INSERT INTO words_users (uid) VALUES (1), (2);

INSERT INTO words_social (sid, social, given, uid) VALUES 
('1111', 10, 'Alice', 1), 
('2222', 20, 'Bob', 2);

双人游戏存储在下表中,chat1chat2列包含player1player2的新聊天消息数量(此处为Alice和Bob在游戏#100中都有1条新留言:

CREATE TABLE words_games (
        gid SERIAL PRIMARY KEY,
        player1 integer REFERENCES words_users(uid) ON DELETE CASCADE NOT NULL CHECK (player1 <> player2),
        player2 integer REFERENCES words_users(uid) ON DELETE CASCADE,
        chat1 integer NOT NULL,
        chat2 integer NOT NULL
);

INSERT INTO words_games (gid, player1, player2, chat1, chat2) 
VALUES (100, 1, 2, 1, 1);

当用户阅读聊天消息时,我想将相应的列(chat1chat2)重置为0.

我无法使用uid来识别用户,我必须通过sidsocial

所以我试图在游戏#100中重置Bob的新聊天消息的数量:

UPDATE words_games g
SET    CASE WHEN s.uid = g.player1 THEN chat2 = 0 ELSE chat1 = 0 END
FROM   words_social s
WHERE  g.gid    = 100
AND    s.social = 20
AND    s.sid    = '2222'
AND    s.uid IN (g.player1, g.player2);

但是语法错误,因为那里不允许CASE

请问有人在这里有个好主意吗?

我的问题的背景是我已经a working stored function in pl/pgSQL但是想切换到纯SQL以获得更好的性能。

1 个答案:

答案 0 :(得分:1)

您可以使用两个单独的set子句执行此操作:

UPDATE word_games g
    SET chat2 = (CASE WHEN s.uid = g.player1 THEN 0 ELSE chat2 END),
        chat1 = (CASE WHEN s.uid = g.player1 THEN chat1 ELSE 0 END)
    . . .