PostgreSQL добавляет несколько результатов в массив - PullRequest
0 голосов
/ 12 апреля 2019

Hello Stack Overflow Users,

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

Таблица пользователей довольно проста, но разрешения разбиты по отдельности.

Для примера приведем 3 таблицы: users, user_access, page

ТакжеЯ застрял с PostgreSQL v8.4.

Данные выглядят примерно так:

таблица пользователей

user_id,username
1,bob
2,cindy
3,jen

таблица user_access

id,user_id,page_id,allowed
1,1,5,true
2,1,7,true
3,1,8,false
4,2,4,true
5,2,5,true
6,2,7,false
7,3,1,true
8,3,5,false

таблица страниц

page_id,page_name
1,report_1
2,report_2
3,report_3
4,admin
5,users
6,options
7,addl_options
8,advanced

До сих пор я был в состоянии создать массив для разрешений, но я 'Я получаю только разрешение на одну страницу и показываю, разрешено это или нет.Мне трудно понять, как собрать остальные страницы и установить их в одной ячейке для каждого пользователя.

Что у меня есть:

select users.user_id, users.username,
    (select array(select page.page_name || ':' || user_access.allowed)
        where users.user_id = user_access.user_id and page.page_id = user_access.page_id) as permissions
from users
    full join user_access on users.user_id = user_access.user_id
    full join page on page.page_id = user_access.page_id;

Но это только возвращает результаты, подобные следующим:

user_id,username,permissions
1,bob,{report_1:<null>}
1,bob,{report_2:<null>}
1,bob,{report_3:<null>}
1,bob,{admin:<null>}
1,bob,{users:true}
1,bob,{options:<null>}
1,bob,{addl_options:true}
1,bob,{advanced:false}

Вместо этого я хочу получить все разрешения для каждой записи пользователя, как это:

user_id,username,permissions        (where permissions is an array of <page_name>:<allowed>)
1,bob,{report_1:<null>,report_2:<null>,report_3:<null>,admin:<null>,users:true,options:<null>,addl_options:true,advanced:false}
2,cindy,{report_1:<null>,report_2:<null>,report_3:<null>,admin:true,users:true,options:<null>,addl_options:false,advanced:<null>}
3,jen,{report_1:true,report_2:<null>,report_3:<null>,admin:<null>,users:false,options:<null>,addl_options:<null>,advanced:<null>}

Я ценю любые советыВы могли бы помочь с.

Спасибо!

1 Ответ

1 голос
/ 12 апреля 2019

Вам необходимо перекрестное соединение между пользователями и страницей, а затем внешнее соединение с разрешениями.Затем результат должен быть сгруппирован:

select u.user_id, array_agg(concat(p.page_name, ':', coalesce(ua.allowed::text, '<null>')) order by p.page_name)
from users u
  cross join page p
  left join user_access ua on ua.page_id = p.page_id and ua.user_id = u.user_id
group by u.user_id;  

Онлайн-пример: https://rextester.com/XYC99067

(В онлайн-примере я использовал string_agg() вместо array_agg(), так как rextester не делает 'красиво отображать массивы)

...