[英]Write a Postgres Get or Create SQL Query
我想寫一個Postgres SQL語句,說明尋找具有顏色X和亮度Y的用戶。如果該用戶存在,則返回其所有行數據。 如果沒有,請創建一個新行並傳遞其他信息。 這兩個單獨的陳述會做這樣的事情:
Select (color, brightness, size, age) FROM mytable WHERE color = 'X' AND brightness= 'Y';
如果這不返回任何內容,則執行以下命令:
INSERT INTO mytable (color, brightness, size, age) VALUES (X, Y, big, old);
有沒有辦法將這些組合成一個查詢?
在SQL DBMS中,select-test-insert方法是一個錯誤:沒有什么可以防止另一個進程在select
和insert
語句之間插入“missing”行。 改為:
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';
您應該能夠將整個文本作為單個“查詢”傳遞給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
如果您的列參與唯一索引約束,則可以使用自9.5版以來可用的方法:
INSERT INTO mytable (color, brightness, size, age)
VALUES ('X', 'Y', 'big', 'old')
ON CONFLICT (color) DO NOTHING;
(假設你有獨特的color
索引)。
文檔是gere: https ://www.postgresql.org/docs/9.5/static/sql-insert.html
在此添加我的解決方案 它與@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';
我發現astef的解決方案不適合我的目的:它不執行“獲取或創建”的“獲取”部分! 如果該值已存在,則不會發生任何事情。
語句末尾的聯合確保如果未插入值(因為它已經存在),我們仍然從表中檢索該值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.