我为我的问题准备了一个简单的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);
双人游戏存储在下表中,chat1
和chat2
列包含player1
或player2
的新聊天消息数量(此处为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);
当用户阅读聊天消息时,我想将相应的列(chat1
或chat2
)重置为0.
我无法使用uid
来识别用户,我必须通过sid
和social
。
所以我试图在游戏#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以获得更好的性能。
答案 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)
. . .