在 Postgres 中有条件地插入匹配条件的行数
Insert conditionally on number of rows matching condition in Postgres
我有一个 table 这样的:
create table if not exists features (
username text not null,
feature text not null,
attributes text[] not null,
primary key(username, feature)
);
我想为用户插入一个新功能,但前提是他们当前在 table 中的功能少于 2 个。如果用户已经在 table.
中拥有该功能,我还想更新该功能的属性
这是我目前得到的:
with f (username, feature, attributes, fcount) as (
values (
'bob', 'dashboard', '{"theme=dark"}'::text[],
(select count(*) from features where username = 'bob' and feature = 'dashboard')
)
)
insert into features (
username,
feature,
attributes
)
select username, feature, attributes
from f
where fcount < 2
on conflict (username, feature)
do update set attributes = excluded.attributes
;
当我 运行 这三次使用不同的特征名称时,它会添加三行而不是 2 行。
username feature attributes
bob dashboard theme=dark
bob dashboard1 theme=dark
bob dashboard2 theme=dark
我怎样才能做到这一点?是否可以使用单个插入查询来执行此操作,还是我需要使用事务和多个查询?
主要问题 - 括号中的 select 列表给出了一个元组,而不是单独的列。此外,值子句中的 attributes
应显式转换为 text[].
还要注意 on conflict
部分中特殊记录 excluded
的正确使用。
with f (username, feature, attributes, fcount) as (
values (
'bob', 'dashboard', '{"theme=dark"}'::text[],
(select count(*) from features where username = 'bob')
)
)
insert into features (
username,
feature,
attributes
)
select username, feature, attributes
from f
where fcount < 2
on conflict (username, feature)
do update set attributes = excluded.attributes;
我有一个 table 这样的:
create table if not exists features (
username text not null,
feature text not null,
attributes text[] not null,
primary key(username, feature)
);
我想为用户插入一个新功能,但前提是他们当前在 table 中的功能少于 2 个。如果用户已经在 table.
中拥有该功能,我还想更新该功能的属性这是我目前得到的:
with f (username, feature, attributes, fcount) as (
values (
'bob', 'dashboard', '{"theme=dark"}'::text[],
(select count(*) from features where username = 'bob' and feature = 'dashboard')
)
)
insert into features (
username,
feature,
attributes
)
select username, feature, attributes
from f
where fcount < 2
on conflict (username, feature)
do update set attributes = excluded.attributes
;
当我 运行 这三次使用不同的特征名称时,它会添加三行而不是 2 行。
username feature attributes
bob dashboard theme=dark
bob dashboard1 theme=dark
bob dashboard2 theme=dark
我怎样才能做到这一点?是否可以使用单个插入查询来执行此操作,还是我需要使用事务和多个查询?
主要问题 - 括号中的 select 列表给出了一个元组,而不是单独的列。此外,值子句中的 attributes
应显式转换为 text[].
还要注意 on conflict
部分中特殊记录 excluded
的正确使用。
with f (username, feature, attributes, fcount) as (
values (
'bob', 'dashboard', '{"theme=dark"}'::text[],
(select count(*) from features where username = 'bob')
)
)
insert into features (
username,
feature,
attributes
)
select username, feature, attributes
from f
where fcount < 2
on conflict (username, feature)
do update set attributes = excluded.attributes;