Как вытащить уникальные слова в PostgreSQL

Рейтинг: 0Ответов: 1Опубликовано: 09.02.2023
coalesce(case when main_parse_user.bio is distinct from EXCLUDED.bio
      and EXCLUDED.bio is not null 
     then concat(trim(main_parse_user.bio), ' ', trim(EXCLUDED.bio)) 
     else main_parse_user.bio end)

Эта часть моего кода для добавление в бд

Туда приходит текст и код должен сравнить то что пришло и то что в бд и надо брать из текста который вводился те слова которых нету в бд

ПРИМЕР

То что в базе
|id|bio|
| 1|qwerty|

INPUT
|id|bio|
| 1|qwerty new|

База после INSERT
|id|     bio     |
| 1|qwerty | new |

Как можно такое сделать?

Полный код

INSERT INTO main_parse_user ("user_id","group_id", "username","bio", "first_name","url") VALUES (%s,%s,%s,%s,%s,%s) 
ON CONFLICT (user_id) 
DO UPDATE SET (group_id,username,bio,first_name) = (EXCLUDED.group_id,EXCLUDED.username, coalesce(case when main_parse_user.bio is distinct from 
EXCLUDED.bio and EXCLUDED.bio is not null then 
concat(trim(main_parse_user.bio), ' | ', trim(EXCLUDED.bio)) else main_parse_user.bio 
end  ),EXCLUDED.first_name)'''

НОВАЯ ЧАСТЬ

INSERT INTO main_parse_user 
("user_id","group_id", "username", "bio", "first_name","url") 
VALUES (%s,%s,%s,%s,%s,%s) ON CONFLICT (user_id) 
DO UPDATE SET (group_id,username,bio,first_name) = (EXCLUDED.group_id,EXCLUDED.username,
(SELECT array_agg(f order by f) FROM (SELECT * FROM UNNEST(main_parse_user.bio) as x(f) UNION 
SELECT * FROM UNNEST(EXCLUDED.bio)  as x(f)) d),EXCLUDED.first_name)

Все ли я правильно сделал в своем варианте?

У меня код выдает ошибку как InvalidTextRepresentation

Cтруктура БД

CREATE TABLE IF NOT EXISTS public.main_parse_user
(
    id bigint NOT NULL DEFAULT nextval('main_parse_user_id_seq'::regclass),
    user_id bigint,
    group_id bigint,
    username character varying(150) COLLATE pg_catalog."default" NOT NULL,
    bio text[] COLLATE pg_catalog."default" NOT NULL,
    first_name text COLLATE pg_catalog."default",
    url text COLLATE pg_catalog."default",
    CONSTRAINT main_parse_user_pkey PRIMARY KEY (id),
    CONSTRAINT main_parse_user_user_id_key UNIQUE (user_id)
)

TABLESPACE pg_default;

ALTER TABLE IF EXISTS public.main_parse_user
    OWNER to postgres;

Ответы

▲ 1Принят

Я советую хранить bio как массив строк text[], это упрощает работу

Ниже как бы выглядел код, если бы bio был массивом

create table tbl (id int primary key, bio text[]);

insert into tbl (id, bio) 
select 2 as id, string_to_array('a b c', ' ') as bio
on conflict(id)
do update set bio = (
  select array_agg(f order by f) from (
    select * from unnest(tbl.bio) as x(f)
    union 
    select * from unnest(EXCLUDED.bio)  as x(f)
  ) d
);


insert into tbl (id, bio) 
select 2 as id, string_to_array('d a e c', ' ') as bio
on conflict(id)
do update set bio = (
  select array_agg(f order by f) from (
    select * from unnest(tbl.bio) as x(f)
    union 
    select * from unnest(EXCLUDED.bio)  as x(f)
  ) d
);


select * from tbl;
id bio
2 a,b,c,d,e

View on DB Fiddle


Переписать на хранение текста с разделителем | тоже можно, но это уже сам.