Sql 要从多个数据中选择单个查询中提到的所有数据吗

Sql 要从多个数据中选择单个查询中提到的所有数据吗,sql,postgresql,Sql,Postgresql,**我正在使用postgres db 我的桌子如下 表1: 列:: 表2 科尔斯:: 限制条件: 我编写的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

**我正在使用postgres db

我的桌子如下

表1:

列::

表2

科尔斯::

限制条件:

我编写的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
是的,你可以。您需要一个聚合查询。如果希望结果为字符串,请执行以下操作:

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中,数组比字符串更有用。您可以将等效数组_agg用于数组结果。

与其加入一个角色,不如加入一个用户拥有的所有角色的字符串。您可以通过按用户名聚合并使用string_agg来实现这一点


如果您只希望用户具有角色,请将其设置为内部联接。

旁注:与您的姓名保持一致。从表名user_details中,我认为应该有一个包含用户的users表,这个details表包含每个用户的多个详细信息。我甚至害怕键/值表,因为这不是所谓的用户地址、用户爱好等。但后来我看到它只是一个名称混乱的用户表。在这个表中,用户有一个ID和一个由三部分组成的名称。但是,在user_角色中,有一个名为user_name。然而,幸运的是,这不是共同分类的名称,而是ID。那么为什么在这里称为名称呢?至于数据模型:我希望还有两个表:一个用于组织,一个用于角色。如果没有它们,您可能会导致组织和角色成倍增加,拼写错误为“组织1”、“组织1”、“组织1”、“组织1”和“角色注册用户”、“角色注册用户”,…非常感谢您的宝贵建议@Thorsten我确实有一个表,用于维护角色字符串role_REGISTEREDUSER等,但我只是没有遇到问题,只是想表达我的需求
FK==>user_roles(user_name) reference user_details(user_id)
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 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
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;
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;