首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >两个表之间在postgres中的联接、聚合和转换

两个表之间在postgres中的联接、聚合和转换
EN

Stack Overflow用户
提问于 2016-01-17 18:17:17
回答 2查看 484关注 0票数 2

下面是我拥有的两个表:两个表中的所有列都是"text“类型,表名和列名都是粗体字体。

名字

代码语言:javascript
复制
--------------------------------
Name     |    DoB   |     Team |
--------------------------------
Harry    |  3/12/85 |  England  
Kevin    |  8/07/86 |  England  
James    |  5/05/89 |  England  

分值

代码语言:javascript
复制
------------------------
ScoreName  |   Score   
------------------------
James-1    |   120      
Harry-1    |   30      
Harry-2    |   40      
James-2    |   56      

我需要的最终结果是一个具有以下内容的表

NameScores

代码语言:javascript
复制
---------------------------------------------
Name     |    DoB   |     Team |   ScoreData
---------------------------------------------
Harry    |  3/12/85 |  England  | "{"ScoreName":"Harry-1", "Score":"30"}, {"ScoreName":"Harry-2", "Score":"40"}" 
Kevin    |  8/07/86 |  England  | null
James    |  5/05/89 |  England  | "{"ScoreName":"James-1", "Score":"120"}, {"ScoreName":"James-2", "Score":"56"}"

我需要使用一个SQL命令来完成这个任务,我将使用这个命令来创建一个物化视图。

我已经意识到它将涉及string_agg、JOIN和JSON的组合,但是还没有完全破解它。(请帮助:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-17 18:31:25

我不认为join是棘手的。复杂的是构建JSON对象:

代码语言:javascript
复制
select n.name, n.dob, n.team,
       json_agg(json_build_object('ScoreName', s.name,
                                  'Score', s.score)) as ScoreData
from names n left join
     scores s
     ons.name like concat(s.name, '-', '%')
group by n.name, n.dob, n.team;

注:json_build_object()是在Postgres 9.4中引入的。

编辑:

我认为您可以添加一个case语句来获得简单的NULL

代码语言:javascript
复制
       (case when s.name is null then NULL
             else json_agg(json_build_object('ScoreName', s.name,
                                             'Score', s.score))
        end) as ScoreData
票数 3
EN

Stack Overflow用户

发布于 2016-01-17 18:34:18

使用json_agg()row_to_json()将分数数据聚合为json值:

代码语言:javascript
复制
select n.*, json_agg(row_to_json(s)) "ScoreData"
from "Names" n
left join "Scores" s
on n."Name" = regexp_replace(s."ScoreName", '(.*)-.*', '\1')
group by 1, 2, 3;

 Name  |   DoB   |  Team   |                                 ScoreData                                 
-------+---------+---------+---------------------------------------------------------------------------
 Harry | 3/12/85 | England | [{"ScoreName":"Harry-1","Score":30}, {"ScoreName":"Harry-2","Score":40}]
 James | 5/05/89 | England | [{"ScoreName":"James-1","Score":120}, {"ScoreName":"James-2","Score":56}]
 Kevin | 8/07/86 | England | [null]
(3 rows)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34841885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档