从postgresql返回不同的数据类型

时间:2016-05-11 15:44:06

标签: json postgresql

我在PG中有以下查询

SELECT
project.project_id,
project.project_name,
   category.category_name,
   array_agg(row(skill.skill_name,projects_skills.projects_skills_id)) AS skills
  FROM project
    JOIN projects_skills ON project.project_id = projects_skills.project_id
    JOIN skill ON projects_skills.skill_id = skill.skill_id
    JOIN category ON project.category_id = category.category_id
 GROUP BY project.project_name,project.project_id, category.category_name;
特别感兴趣的是以下似乎返回伪类元组的行

array_agg(row(skill.skill_name,projects_skills.projects_skills_id)) AS skills

由于伪类型,我无法创建此视图 - 除此之外,行函数似乎返回如下所示的元组集:

skills: '{"(Python,3)","(Node,4)","(Javascript,5)"}' } 

我可以通过替换'('到' ['等等]来痛苦地在JavaScript中解析它但我可以在postgres中做一些事情来将它作为对象返回吗?

2 个答案:

答案 0 :(得分:1)

一种可能的解决方案是注册行类型(一次):

CREATE TYPE my_type AS (skill_name text, projects_skills_id int);

我猜测textint是数据类型。使用基础表的实际数据类型。

SELECT p.project_id, p.project_name, c.category_name
     , array_agg((s.skill_name, ps.projects_skills_id)::my_type) AS skills
FROM   project          p
JOIN   projects_skills ps ON p.project_id = ps.project_id
JOIN   skill            s ON ps.skill_id = s.skill_id
JOIN   category         c ON p.category_id = c.category_id
GROUP  BY p.project_id, p.project_name, c.category_name;

还有很多其他选项,具体取决于您的Postgres版本以及您需要的内容。

答案 1 :(得分:0)

除了在评论中使用JSON的优秀建议,以及@Erwin使用已注册的复合类型,您可以使用二维数组或多值方法:

只需更换行

即可
array_agg(row(skill.skill_name::text,projects_skills.projects_skills_id::text)) AS skills

以下内容:

二维数组选项1

array_agg(array[skill.skill_name::text,projects_skills.projects_skills_id::text]) AS skills

-- skills will be '{{Python,3},{Node,4},{Javascript,5}}', thus
-- skills[1][1] = 'Python' and skills[1][2] = '3' -- id is text

二维数组选项2

array[array_agg(skill.skill_name),array_agg(projects_skills.projects_skills_id)] AS skills

-- skills will be '{{Python,Node,Javascript},{3,4,5}}', thus
-- skills[1][1] = 'Python' and skills[2][1] = '3' -- id is text

的多元分析

array_agg(skill.skill_name) AS skill_names,
array_agg(projects_skills.projects_skills_id) AS skills_ids

-- skills_names = '{Python,Node,Javascript}' and skill_ids = '{3,4,5}', thus
-- skills_names[1] = 'Python' and skills_ids[1] = 3 -- id is integer