簡體   English   中英

Postgresql 從另一列中減去一列中的逗號分隔字符串

[英]Postgresql subtract comma separated string in one column from another column

格式如下:

col1 col2
V1,V2,V3,V4,V5,V6 V4,V1,V6
V1,V2,V3 V2,V3

我想創建另一個名為 col3 的列,其中包含兩列的減法。

我試過的:

UPDATE myTable
SET col3=(replace(col1,col2,''))

它適用於像 row2 這樣的行,因為替換模式的順序很重要。

我想知道是否有一種完美的方法可以為 row1 之類的行實現相同的目標。

所以所需的輸出將是:

col1 col2 col3
V1,V2,V3,V4,V5,V6 V4,V1,V6 V2,V3,V5
V1,V2,V3 V2,V3 V1

任何建議,將不勝感激!

將值拆分為表格,減去集合,然后將其組合回來。 一切都可以作為定義新查詢列的表達式。

with t (col1,col2) as (values
('V1,V2,V3,V4,V5,V6','V4,V1,V6'),
('V1,V2,V3','V2,V3')
)
select col1,col2
     , (
         select string_agg(v,',')
         from (
           select v from unnest(string_to_array(t.col1,',')) as a1(v)
           except
           select v from unnest(string_to_array(t.col2,',')) as a2(v)
         ) x
        )
from t

數據庫小提琴

您必須取消嵌套元素,然后在“未嵌套”行上應用 EXCEPT 子句並聚合回來:

select col1, 
       col2, 
       (select string_agg(item,',' order by item)
        from (
           select *
           from string_to_table(col1, ',') as c1(item)
           except 
           select *
           from string_to_table(col2, ',') as c2(item)
        ) t)
from the_table;        
           

我不會將該結果存儲在單獨的列中,但如果您確實需要通過存儲另一個逗號分隔列表來引入更多問題。

update the_table
  set col3 =  (select string_agg(item,',' order by item)
               from (
                  select *
                  from string_to_table(col1, ',') as c1(item)
                  except 
                  select *
                  from string_to_table(col2, ',') as c2(item)
               ) t)
;

string_to_table()需要 Postgres 14 或更高版本。 如果您使用的是舊版本,則需要使用unnest(string_to_array(col1, ','))代替


如果您需要很多,請考慮創建一個函數:

create function remove_items(p_one text, p_other text)
  returns text
as
$$
  select string_agg(item,',' order by item)
  from (
     select *
     from string_to_table(col1, ',') as c1(item)
     except 
     select *
     from string_to_table(col2, ',') as c2(item)
  ) t;
$$
language sql
immutable;

那么上面的可以簡化為:

select col1, col2, remove_items(col1, col2)
from the_table;

請注意, POSTGRESQL不是我的強項,但我想我會嘗試一下。 嘗試:

SELECT col1, col2, RTRIM(REGEXP_REPLACE(Col1,CONCAT('\m(?:', REPLACE(Col2,',','|'),')\M,?'),'','g'), ',') as col3 FROM myTable

查看在線文件


這個想法是使用常規表達式來替換所有值,基於以下模式:

  • \m - 單詞開頭的單詞邊界;
  • (?:V4|V1|V6) - 一個非捕獲組,包含 col2 的備選方案;
  • \M - 詞尾的詞邊界;
  • ,? - 可選逗號。

當替換為空時,我們需要使用RTRIM()清理可能的尾隨逗號。 請參閱在線演示,我必須將單詞邊界替換為\b單詞邊界以展示結果。

暫無
暫無

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

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