Reputation: 22958
I have prepared a simple SQL Fiddle for my question.
In PostgreSQL 10 user ids are stored in words_users
table, but their names are stored in words_social
table:
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);
Two-player games are stored in the following table, with chat1
and chat2
columns holding number of new chat messages for player1
or player2
(here Alice and Bob both have 1 new message waiting in the game #100):
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);
When a user reads her chat messages, I would like to reset the corresponding column (chat1
or chat2
) back to 0.
And I can not use uid
to identify the user, I have to go via sid
and social
.
So I am trying to reset the number of new chat messages for Bob in game #100:
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);
but get a syntax error, because CASE
is not allowed there.
Does anybody please have a good suggestion here?
The background of my question is that I have already a working stored function in pl/pgSQL but would like to switch to pure SQL for better performance.
Upvotes: 0
Views: 56
Reputation: 1269503
You can do this with two separate set
clauses:
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)
. . .
Upvotes: 1