我想写一个Postgres SQL语句,说明寻找具有颜色X和亮度Y的用户.如果该用户存在,则返回其所有行数据.如果没有,请创建一个新行并传递其他信息.这两个单独的陈述会做这样的事情:
Select (color, brightness, size, age) FROM mytable WHERE color = 'X' AND brightness= 'Y';
Run Code Online (Sandbox Code Playgroud)
如果这不返回任何内容,则执行以下命令:
INSERT INTO mytable (color, brightness, size, age) VALUES (X, Y, big, old);
Run Code Online (Sandbox Code Playgroud)
有没有办法将这些组合成一个查询?
Jam*_*den 21
在SQL数据库管理系统,选择试验插入的做法是错误的:没有什么能阻止另一进程将您的"失踪"的行select
和insert
语句.改为:
insert into mytable (color, brightness, size, age)
select color, brightness, size, age
from mytable
where not exists (
select 1 from
from mytable
where color = 'X' and brightness = 'Y'
);
SELECT (color, brightness, size, age)
FROM mytable
WHERE color = 'X' AND brightness= 'Y';
Run Code Online (Sandbox Code Playgroud)
您应该能够将整个文本作为单个"查询"传递给DBMS.您可能需要考虑将其变为存储过程.
with sel as (
select color, brightness, size, age
from mytable
where color = 'X' and brightness = 'Y'
), ins as (
insert into mytable (color, brightness, size, age)
select 'X', 'Y', 6.2, 40
where not exists (
select 1 from sel
)
returning color, brightness, size, age
)
select color, brightness, size, age
from ins
union
select color, brightness, size, age
from sel
Run Code Online (Sandbox Code Playgroud)
如果您的列参与唯一索引约束,您可以使用自版本 9.5 以来可用的方法:
INSERT INTO mytable (color, brightness, size, age)
VALUES ('X', 'Y', 'big', 'old')
ON CONFLICT (color) DO NOTHING;
Run Code Online (Sandbox Code Playgroud)
(假设您有唯一索引color
)。
文档在这里:postgresql 9.5
在此处添加我的解决方案。它与@Clodoaldo Neto 和@astef 的解决方案略有不同。
WITH ins AS (
INSERT INTO mytable (color, brightness, size, age)
VALUES ('X', 'Y', 'big', 'old')
ON CONFLICT (color) DO NOTHING
RETURNING *
)
SELECT * FROM ins
UNION
SELECT * FROM mytable
WHERE color = 'X';
Run Code Online (Sandbox Code Playgroud)
我发现 astef 的解决方案不足以满足我的目的:它不执行“获取或创建”的“获取”部分!如果该值已经存在,则什么都不会发生。
语句末尾的联合确保如果值没有插入(因为它已经存在),我们仍然从表中检索该值。
归档时间: |
|
查看次数: |
6039 次 |
最近记录: |