【问题标题】:SQL select return keyed object from joinsSQL 选择从连接中返回键控对象
【发布时间】:2020-09-08 16:25:17
【问题描述】:

我有一个有效的 SQL 查询 (Postgres 9.6),它返回我需要的信息,但它并没有完全符合我的要求。

SELECT ARRAY(
  SELECT
    row_to_json(a.*)
  FROM (
    SELECT
      proj.slug,
      perm.name AS role
    FROM "Projects" proj
    INNER JOIN "Permissions" perm
    ON perm.project_id = proj.id
    INNER JOIN "UserPermissions" up
    ON up.permission_id = perm.id
    WHERE up.user_id = 1
    ORDER BY lower(proj.name)
  ) a
) as permissions

使用此查询,权限位于一个看起来像这样的数组中

[
  {
    slug: 'abcdef',  
    role: 'owner' 
  },
  { 
    slug: 'abcdef', 
    role: 'admin' 
  },
  {
    slug: 'ghijkl',
    role: 'member'
  }
]

我想将权限作为一个对象来获取,通过slug将项目组合在一起:

{
  'abcdef': {
    slug: 'abcdef',
    roles: ['owner', 'admin']
  },
  'ghijkl': {
    slug: 'ghijkl',
    roles: ['member']
  }
}

目前我正在使用应用程序代码查询后执行此操作。

有没有办法通过 SQL 查询直接返回这个形状?

【问题讨论】:

  • PostgreSQL 9 表示 9.4/9.5/9.6?
  • @AkhileshMishra 9.6 -- 更新

标签: sql arrays json postgresql where-clause


【解决方案1】:

我认为您需要两个级别的聚合。首先,将与每个slug关联的角色收集到一个json数组中(使用JSON_AGG()),然后生成目标json对象,使用JSON_OBJECT_AGG()

SELECT JSON_OBJECT_AGG(slug, JSON_BUILD_OBJECT('slug', slug, 'roles', roles)) permissions
from (
    SELECT pr.slug, json_agg(pe.name) as roles
    FROM "Projects" pr
    INNER JOIN "Permissions" pe ON pe.project_id = pr.id
    INNER JOIN "UserPermissions" up ON up.permission_id = pe.id
    WHERE up.user_id = 1
    GROUP BY pr.slug
) t

【讨论】:

    猜你喜欢
    • 2021-04-02
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多