2015-01-08 2 views
0

Из этих таблиц:

select group, ids 
from some.groups_and_ids; 

Результат:

group | group_ids 
    ---+---- 
winners | 1$4 
losers | 4 
others | 2$3$4 

и:

select id,name from some.ids_and_names; 

id | name 
---+---- 
1 | bob 
2 | robert 
3 | dingus 
4 | norbert 

Как бы вы о возвращении что-то вроде:

winners | bob, norbert 
losers | norbert 
others | robert, dingus, norbert 
+3

Вы не должны хранить разделителями значения в одном столбце, в первую очередь. Было бы лучше, если бы вы нормализовали свою базу данных. –

ответ

0

Возможно ли редизайн вашей базы данных? Включение всех group_ids в один столбец усложняет жизнь. Если ваша таблица была, например,

group | group_id 

winners | 1 
winners | 4 
losers | 4 

и т. Д. Это было бы просто легко. Как бы то ни было, нижний запрос будет делать это, хотя я не решался опубликовать его, поскольку он поощряет плохой дизайн базы данных (IMHO)!

p.s. Я взял на себя смелость переименовать несколько столбцов, потому что они зарезервированные слова. Вы можете избежать их, но зачем делать жизнь трудной для себя?

select group_name,array_to_string(array_agg(username),', ') -- array aggregation and make it into a string 
from 

(
select group_name,theids,username 
from ids_and_names 
inner join 

(select group_name,unnest(string_to_array(group_ids,'$')) as theids -- unnest a string_to_array to get rows 

from groups_and_ids) i 
on i.theids = cast(id as text)) a 
group by group_name 
1
with normalized (group_name, id) as (
    select group_name, unnest(string_to_array(group_ids,'$')::int[]) 
    from groups_and_ids 
) 
select n.group_name, string_agg(p.name,',' order by p.name) 
from normalized n 
    join ids_and_names p on p.id = n.id 
group by n.group_name; 

Первая часть (common table expression) нормализует ваш сломанный дизайн таблицы, создавая правильный взгляд на groups_and_ids столе. Фактический запрос затем присоединяет таблицу ids_and_names к нормализованной версии ваших групп и агрегирует имена снова.

Примечание. Я переименовал group в group_name, поскольку group является зарезервированным ключевым словом.

SQLFiddle: http://sqlfiddle.com/#!15/2205b/2

+0

Этот ответ более чист, чем мой. Использование «с помощью» делает запрос более понятным, а листинг массива внутри «с» делает все, что немного чище. Это также делает недостатки в дизайне стола очевидными! – mlinth

+0

Как бы вы отсортировали имена, которые возвращены? :) – user3486527

+0

@ user3486527: с 'order by';) (см. Мое редактирование) –

Смежные вопросы