我在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
有人可以建议解决此问题或其他方法吗?
由于
答案 0 :(得分: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';