Хотите выделить все упомянутые данные в одном запросе, сформировать несколько данных - PullRequest
0 голосов
/ 26 мая 2018

** Я использую postgres db

Мои таблицы выглядят следующим образом

таблица 1 ::

user_details

столбцы::

user_id,first_name,middle_name,last_name,organisation

table2

user_roles

cols ::

id,user_name,role

Ограничения ::

FK==>user_roles(user_name) reference user_details(user_id)

SQL-запрос, который я написал:

SELECT  ud.user_id,
    ud.organisation,
    CONCAT(COALESCE(ud.first_name,''),' ',COALESCE(ud.middle_name,''),' ',COALESCE(ud.last_name,'')) AS full_name,
    ur.role
    FROM user_details ud
    INNER JOIN user_roles ur ON ud.user_id = ur.username;

, который дает мне данные в виде ::

user_id | organisation   | full_name         | role
--------+----------------+-------------------+--------------------
user1   | organisation 1 | first middle last | ROLE_REGISTEREDUSER
user1   | organisation 1 | first middle last | ROLE_ADMIN
user 2  | org 2          | first middle last | ROLE_REGISTEREDUSER
user 2  | org 2          | first middle last | ROLE_ADMIN

КакЕсть несколько ролей, я получаю 2 строки для каждого пользователя.Есть ли способ объединить роли и получить по одной строке для каждого пользователя с объединенными ролями следующим образом:

user_id | organisation   | full_name         | role
--------+----------------+-------------------+-------------------------------
user1   | organisation 1 | first middle last | ROLE_REGISTEREDUSER,ROLE_ADMIN
user 2  | org 2          | first middle last | ROLE_REGISTEREDUSER,ROLE_ADMIN

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Вместо того, чтобы присоединяться к одной роли, объедините строку всех ролей, которые имеет пользователь.Вы получаете это путем агрегирования по имени пользователя и использования string_agg.

select
  ud.user_id,
  ud.organisation,
  concat_ws(' ', ud.first_name, ud.middle_name, ud.last_name) as full_name,
  ur.roles
from user_details ud
left join
(
  select username, string_agg(role, ',' order by role) as roles
  from user_roles
  group by username
) ur on ur.username = ud.user_id;

Сделайте это внутренним объединением, если вы хотите, чтобы пользователи имели роли.

0 голосов
/ 26 мая 2018

Да, вы можете.Вам нужен запрос агрегации.Если вы хотите получить результат в виде строки:

SELECT ud.user_id, ud.organisation,
       CONCAT(COALESCE(ud.first_name, ''), ' ', COALESCE(ud.middle_name,''), ' ', COALESCE(ud.last_name,'')) AS full_name,
       STRING_AGG(ur.role, ',' ORDER BY ur.role) as roles
FROM user_details ud INNER JOIN
     user_roles ur
     ON ud.user_id = ur.username
GROUP BY user_id, organization, full_name;

Часто в Postgres массив более полезен, чем строка.Вместо этого вы можете использовать эквивалент array_agg() для результата массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...