3

I am essentially asking the same questions as Switch values between rows in unique column but for PostgreSQL.

My situation is a bit more complex: I have a uniqueness constraint on several columns, let's say columns a and b. I want to exchange values in column b between rows, so for examples

id | a   | b
1  | "a" | 0
2  | "a" | 1
3  | "b" | 0
4  | "b" | 1

The desired result is,

id | a   | b
1  | "a" | 1
2  | "a" | 0
3  | "b" | 1
4  | "b" | 0

I have tried the following natural snippet of code: UPDATE table SET b = CASE WHEN b=0 THEN 1 ELSE 0 END WHERE id <= 4; (the WHERE part is something more complex in my case but it should change nothing).

What I get in the end is that the uniqueness constraint fails, and I don't have any ideas of what else to try.

1

1 Answer 1

4

You need a deferrable constraint, e.g.:

create table my_table(
    id int primary key, 
    a text, 
    b int, 
    unique(a, b) deferrable);

Set the constraint to be deferred in the transaction:

begin;
set constraints all deferred;
update my_table set 
    b = case when b = 0 then 1 else 0 end 
where id <= 4;
commit;

Test it in Db<>Fiddle.

Read in the documentation: CREATE TABLE and SET CONSTRAINTS.

Note, you can define the constraint as deferrable initially deferred, then you do not have to set the constraint before update.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.