The correct answer is: Normalize your tables. Storing comma separated values is almost always a bad idea.
The usual reaction to that recommendation is: "I can't change the design, am I'm not responsible for it".
So if you really, really have to keep this broken design and want to fight symptons rather than fixing the cause of the problem you could do something like this:
Code:
select p.id, p.name, l.id, l.descr
from languages l
join (
select id, name, regexp_split_to_table(lang_id, ',') as lid
from people
) p on p.lid::integer = l.id
A
much better and cleaner solution however is to add a table linking people to languages:
Code:
create table languages
(
id int not null primary key,
descr varchar
);
create table people
(
id int not null primary key,
name varchar
);
create table speaks
(
person_id int not null references people,
lang_id int not null references languages,
primary key (person_id, lang_id)
);
insert into languages
values
(1,'English'),
(2,'Telugu'),
(3,'Hindi');
insert into people
values
(1,'Apple'),
(2,'Grape');
insert into speaks (person_id, lang_id)
values
(1, 1),
(1, 2),
(2, 3),
(2, 1);
select p.id, p.name, l.id, l.descr
from people p
join speaks s on s.person_id = p.id
join languages l on l.id = s.lang_id;
(Note that I changed the colum
desc to
descr because
desc is a reserved word and should not be used as a column name)
This solution has several advantages:
- You can never a language that doesn't exist
- Your statement does not fail if someone enters "foobar" into the lang_id column (of your original table)
- You can ensure that the same language is only assigned once to one person