簡體   English   中英

編寫Postgres獲取或創建SQL查詢

[英]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方法是一個錯誤:沒有什么可以防止另一個進程在selectinsert語句之間插入“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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM