【问题标题】:Postgres join JSON listPostgres 加入 JSON 列表
【发布时间】:2015-08-13 19:06:52
【问题描述】:

我在 postgres 9.4 中加入 JSON 列表时遇到问题

这是我的问题:

表结构:

CREATE TABLE players
(
  id serial NOT NULL,
  player json,
  CONSTRAINT players_pkey PRIMARY KEY (id)
)

CREATE TABLE matches
(
  id serial NOT NULL,
  match json,
  CONSTRAINT matches_pkey PRIMARY KEY (id)
)

样本数据:

players
1;"{"Name":"AAA","Height":186,"Weight":65}"
2;"{"Name":"BBB","Height":195,"Weight":85}"
3;"{"Name":"CCC","Height":175,"Weight":72}"
4;"{"Name":"DDD","Height":168,"Weight":56}"

matches
5;{"Id":1,"Teams":[{"Name":"TeamA","Players":[{"Name":"AAA"},{"Name":"BBB"}]},{"Name":"TeamB","Players":[{"Name":"CCC"},{"Name":"DDD"}]}],"TeamRank":[1,2]}
6;{"Id":2,"Teams":[{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}]},{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}]}],"TeamRank":[1,2]}

每支球队的球员都是该球队上一场比赛中的球员。获取球队名称和球员名单(当前球队)的查询如下:

SELECT DISTINCT ON (t.team->>'Name') t.team
FROM   matches m, json_array_elements(m.match->'Teams') t(team)
ORDER  BY t.team->>'Name', m.id DESC

这将返回以下(团队表):

"{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}]}"
"{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}]}"

我想将上述结果中的每个玩家及其身高和体重加入列表中,以便输出如下:

"{"Name":"TeamA","Players":[{"Name":"CCC","Height":175,"Weight":72},{"Name":"BBB","Height":195,"Weight":85}]}"
"{"Name":"TeamB","Players":[{"Name":"AAA","Height":186,"Weight":65},{"Name":"DDD","Height":168,"Weight":56}]}"

我曾尝试使用 INNER JOIN 来做到这一点:

WITH u AS (SELECT DISTINCT ON (t.team->>'Name') t.team
FROM   matches m, json_array_elements(m.match->'Teams') t(team)   -- FROM ABOVE!!!
ORDER  BY t.team->>'Name', m.id DESC) 

SELECT player FROM (SELECT json_array_elements(team->'Players') FROM u) AS v
INNER JOIN players on v->>'Name'=player->>'Name';

这是朝着我想要的方向迈出的一步,但我收到以下错误:

ERROR: operator does not exist: record ->> unknown
SQL state: 42883
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Character: 2822

任何人都可以提出解决此问题的方法或其他方法吗?

谢谢

【问题讨论】:

    标签: json postgresql join


    【解决方案1】:

    这个:

    (SELECT json_array_elements(team->'Players') FROM u) AS v
    

    v 声明为一个关系,因此在其他地方对v 的任何引用都意味着“此关系中的一条记录”。所以这个:

    v->>'Name'=player->>'Name'
    

    不起作用,因为它试图将 v 用作 JSON 值而不是记录。

    要解决此问题,您需要使用列别名;例如,你可以这样写:

    SELECT player FROM (SELECT json_array_elements(team->'Players') FROM u) AS v(v_player)
    INNER JOIN players on v_player->>'Name' = player->>'Name';
    

    【讨论】:

    • 解决了,非常感谢。 Inner Join 是最好的方法吗?
    • 我仍然需要把它放到上面的输出中,我怎样才能把它和我以前的查询结合起来?
    猜你喜欢
    • 1970-01-01
    • 2021-06-27
    • 2018-08-06
    • 1970-01-01
    • 2023-04-10
    • 2015-08-11
    • 2016-01-31
    • 1970-01-01
    • 2017-05-19
    相关资源
    最近更新 更多