簡體   English   中英

使用 FOR LOOP 和 IF 語句更新 Postgresql 中的列

[英]Using FOR LOOP and IF Statements to UPDATE a Column in Postgresql

我需要在同一個表中使用列 'a_sp' (varchar) 更新列 'sp' (varchar)。 兩列都包含從零/空到多個值列表。 這些值與“+”號連接,並與該符號一起存儲在它的開頭和結尾。 我想遍歷'a_sp'中的每個值並檢查它是否已經存在於其各自的'sp'單元格中。 如果是,則不會將任何內容附加到“sp”,如果不是,則附加該值。 感謝您的幫助,因為我剛剛從 OOP 適應數據庫編程。 表格圖像

UPDATE work.table
SET sp = 
    CASE
    WHEN (sp IS NULL OR sp = '') THEN a_sp --no sp val return a_sp
    WHEN (sp IS NOT NULL OR sp != '') THEN --if there exists sp val
        CASE
        WHEN sp LIKE '%'||a_sp||'%' THEN sp --if existing sport val is          similar to a_sp return sp
        ELSE sp||ltrim(a_sp, '+') --if existing sp val not similar to asp, append
        END
    ELSE sp --if both cases above not met (which is odd) return sp
    END 
    WHERE a_sp IS NOT NULL;

我的解決方案(雖然俗氣) -

--I found the function (below) which creates a distinct array of any array type at https://postgres.cz/wiki/Array_based_functions
CREATE OR REPLACE FUNCTION work.array_distinct(anyarray)
RETURNS anyarray AS $$
  SELECT ARRAY(SELECT DISTINCT unnest($1))
$$ LANGUAGE sql;

--for sp col
UPDATE work.tab
  SET sp = 
    CASE
    WHEN (sp IS NULL OR sp = '') THEN a_sp --no sp val return a_sp
    WHEN (sp IS NOT NULL OR sp != '') THEN
    --below i did quite some manipulations
    --i removed the '+' to the left of a_sp column
    --then concatenated sp and asp columns
    --i converted the concatenated result to array based on the string '+' as a divider
    --next, i used the function 'array_distinct' above to return unique values # this was quite a way to avoid looping through the lists to append
    --i converted the result above back to string with a string '+' separator
    --i finally added string '+' to both ends of my result
    replace(replace('+'||rtrim(array_to_string(array_distinct(regexp_split_to_array(replace(sp||ltrim(a_sp, '+'), '+', ' '), E'\\s+')::varchar[]), ','), ',')||'+',',', '+'), '++', '+') --if there exists sp val
    --ELSE sport --if both cases above not met (which is odd) return sp
    END
    WHERE a_sp IS NOT NULL;

我假設您的代碼有效,而您只是在尋找更好的方法。 在你正在做的單個更新語句中而不是在循環中執行它絕對是 go 的方式,因為它比循環快光年。

您的代碼可能會以更好的方式編寫,減少冗余檢查和不需要更新的更新:

UPDATE work.table
SET sp = CASE WHEN NULLIF(sp, '') IS NULL THEN a_sp ELSE sp || ltrim(a_sp, '+') END
WHERE a_sp IS NOT NULL
AND COALESCE(sp, '') !~ a_sp -- don't perform unnecessary updates

您的 CASE 語句可以稍微簡化 - 如果sp為 NULL/空,請將其設置為a_sp ,否則將其與a_sp 並且添加到WHERE子句中會過濾掉不應更新的情況( sp包含在a_sp中)。


編輯:

sp LIKE '%'||a_sp||'%'不會像您期望的那樣工作,因為它將通配符放在整個a_sp字段的末尾,因此它不會找到a_sp值包含sp的情況substring。 因此,正則表達式是一種簡單的檢查方法,但您也可以通過position function 進行檢查,這就像其他語言中的indexOf

WHERE ...
AND (NULLIF(sp, '') IS NULL OR POSITION(sp IN a_sp) = 0) -- i.e. a_sp does not contain sp

因為POSITION('' IN 'x')為 1,所以在檢查中添加了NULLIF ,但我們不想排除 NULL/空sp行。


編輯2:

我現在明白你想要做什么了。 我認為這只是檢查sp的值是否在a_sp中,如果是,則忽略,如果不是,則連接字段。 但實際上每個字段都包含分隔數據,因此需要將每個字段的數據有效地拆分為多個部分,然后將兩個字段的不同部分重新組合並寫入sp字段。 這實際上是您在解決方案中所做的。 我將在下面再次提出一種稍微不同的方法。

我也明白為什么正則表達式不起作用,這是由於字段中的+符號。 無論如何,鑒於我現在對您正在嘗試做的事情的理解,它不再是一種有效的檢查方式。


設置

CREATE TABLE t (id INTEGER, sp TEXT, a_sp TEXT);

INSERT INTO t
VALUES
(1, '+hk1+', '+rk3+hk1+xk5+'),
(2, '+hk1+hk2+', '+jk8+hk1+'),
(3, NULL, '+hk1+dk7+'),
(4, '', '+hk1+dk7+'),
(5, '+hk3+', NULL),
(6, '+hk2+', '+hk1+');

詢問

UPDATE t
SET sp = (
  SELECT '+' || STRING_AGG(DISTINCT u, '+' ORDER BY u) || '+'
  FROM UNNEST(string_to_array(sp, '+', '') || string_to_array(a_sp, '+', '')) u
  WHERE u IS NOT NULL
)
WHERE a_sp IS NOT NULL;

結果(更新運行后的SELECT * FROM t

| id  | sp            | a_sp          |
| --- | ------------- | ------------- |
| 1   | +hk1+rk3+xk5+ | +rk3+hk1+xk5+ |
| 2   | +hk1+hk2+jk8+ | +jk8+hk1+     |
| 3   | +dk7+hk1+     | +hk1+dk7+     |
| 4   | +dk7+hk1+     | +hk1+dk7+     |
| 5   | +hk3+         |               |
| 6   | +hk1+hk2+     | +hk1+         |

在 DB Fiddle 上查看

子查詢:

  1. 對正在更新的行進行操作
  2. 通過+分隔符拆分兩個字段。 你也可以使用regexp_split_to_array但我決定 go 和string_to_array因為我可以將''設置為 NULL (第三個參數)。
  3. 連接 arrays。 現在您有了一個數組,其中包含兩個字段中的每個值,其中包含一些重復值。
  4. 取消嵌套這個新的組合數組並聚合不同的值,不包括 NULL 值。 還訂購了良好測量的值。 這將創建一個新字符串,其中的值由“+”分隔。
  5. 將前導和尾隨 '+' 添加到新字符串

並將結果寫入sp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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