我有一个Postgres DB设置,并且我正在try 从查询返回特定的数据形状.

我的数据是这样的:

CREATE TABLE resource_actions(
resource TEXT NOT NULL,
actions TEXT NOT NULL,
entity TEXT NOT NULL,
UNIQUE(resource, actions, entity)
);


INSERT INTO resource_actions (resource, actions, entity) VALUES
('reading-list', 'read', 'Citizen'),
('reading-list', 'read', 'Employee'),
('books', 'read', 'Employee'),
('titles', 'update', 'Citizen'),
('titles', 'read', 'Citizen'),
('titles', 'update', 'Employee'),
('titles', 'read', 'Employee'),
('authors', 'update', 'Employee'),
('authors', 'read', 'Citizen'),
('reviews', 'read', 'Citizen'),
('reviews', 'read', 'Employee'),
('reviews', 'create', 'Citizen'),
('reviews', 'create', 'Employee'),
('employees', 'read', 'Employee'),
('employees', 'read', 'Boss'),
('employees', 'delete', 'Boss'),
('employees', 'create', 'Boss'),
('employees', 'update', 'Boss'),
('employee-schedule', 'read', 'Boss'),
('employee-schedule', 'delete', 'Boss'),
('employee-schedule', 'create', 'Boss'),
('employee-schedule', 'update', 'Boss');

我想像这样返回数据:

{
    read:['Citizen':['reading-list', 'titles', 'authors','reviews'], 'Employee':['books','reading-list', 'titles', 'authors'], 'Boss':[]]
    create:['Citizen':['reviews'], 'Employee':['reviews'], 'Boss':['employees','employee-schedule']],
    update: ['Citizen':['titles'], 'Employee':['authors','titles'], 'Boss':['employees','employee-schedule']],
    delete:['Citizen':[], 'Employee':[], 'Boss':['employees','employee-schedule']]
}

我有一个接近的SQL查询,但我无论如何也找不出需要更改哪些内容才能获得正确的数据形状.我的查询如下:

select actions, 
JSON_AGG(JSON_BUILD_OBJECT(resource, entity)) AS groupedActions
FROM resource_actions 
GROUP BY actions

我有一个SQL小提琴,显示了我到目前为止所拥有的:http://sqlfiddle.com/#!17/93bf5/1/0

这让我很接近,但我不明白如何按entity汇总数据并显示他们有权访问的资源的array.如有任何帮助,我们不胜感激!

推荐答案

select json_build_object(actions, array_agg(groupedResources)) as jsonResult
from (select actions, json_build_object(entity, array_agg(resource)) as groupedResources
      from resource_actions
      group by actions, entity) tmp
group by actions;
jsonresult
{"create" : [{"Citizen" : ["reviews"]},{"Employee" : ["reviews"]},{"Boss" : ["employees","employee-schedule"]}]}
{"read" : [{"Boss" : ["employees","employee-schedule"]},{"Citizen" : ["reading-list","titles","authors","reviews"]},{"Employee" : ["reading-list","books","titles","reviews","employees"]}]}
{"update" : [{"Boss" : ["employees","employee-schedule"]},{"Citizen" : ["titles"]},{"Employee" : ["titles","authors"]}]}
{"delete" : [{"Boss" : ["employees","employee-schedule"]}]}

DBfiddle demo

全部作为单一JSON:

select json_agg(jsonResult)
from (
select json_build_object(actions, json_agg(groupedResources)) as jsonResult
from (select actions, json_build_object(entity, array_agg(resource)) as groupedResources
      from resource_actions
      group by actions, entity) tmp
group by actions) x;

DBFiddle demo

Sql相关问答推荐

用于动态查询情况的存储过程常识模式

SQL使最终结果显示两个表后的所有数据(匹配和不匹配)?

在SQL中使用类别值将行转置为列

如何在postgres函数中插入后返回布尔值?

在Oracle SQL中将列值转换为行

查找表中特定值的上次更新日期

我可以在SQL的IN子句中使用比子查询包含的值更少的值吗?

Select 非重复值并按条件排除行

如何使用SQL生成数据的滚动3天总和

通过UPDATE SELECT更新表时出现问题

聚合内部的条件在哪里?

将 json 列键映射到第二个表中的匹配列值

SQL 中的第一个值和倒数第二个值

PostgreSQL - 从同一张表中获取值

SQL - 只需要 GROUP BY SELECT 的一列

查找具有相同连接列数据的所有记录

在给定列中具有特定值的行与 SQL 中的总行数的比率

PlSql 陷入死循环

根据开始/结束标记将 GROUP_ID 分配给行

连续日期的SQL