我目前使用Postgresql 9.6并且一直在尝试从几小时后以最有效的方式解决以下问题:
我的示例表:
id | data
-----------------------------------------------------------------------------------------------------------
10 | {"scores": [{"u": "Peter", s: 120}, {"u": "Joe", s: 100}, {"u": "Pam", s: 70}, {"u": "Lisa", s: 120}]}
11 | {"scores": [{"u": "Mae", s: 320}, {"u": "Max", s: 230}, {"u": "Moe", s: 170}, {"u": "Mini", s: 120}]}
12 | {"scores": [{"u": "Jack", s: 140}, {"u": "John", s: 110}, {"u": "Wes", s: 70}, {"u": "Mick", s: 20}]}
我需要一个查询来获取每行的前2个用户名(u
)。
所以我的结果应该是这样的:
users
-----
Peter
Joe
Mae
Max
Jack
John
获取第二个和第三个用户名的查询:
users
-----
Joe
Pam
Max
Moe
John
Wes
解决这个问题的最有效方法是什么?我的真实表格包含100-400个元素和大约1500行。
答案 0 :(得分:4)
前2个用户名:
SELECT scores -> 'u'
FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY id) rn, scores
FROM (
SELECT id, data, jsonb_array_elements(data -> 'scores') AS scores
FROM scores
) s1
) s2
WHERE rn <= 2;
第二和第三个用户名:
SELECT scores -> 'u'
FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY id) rn, scores
FROM (
SELECT id, data, jsonb_array_elements(data -> 'scores') AS scores
FROM scores
) s1
) s2
WHERE rn = 2 OR rn = 3;
另一种选择是:
SELECT username
FROM (
SELECT unnest(ARRAY [(data #> '{scores,0,u}') :: TEXT, (data #> '{scores,1,u}') :: TEXT]) username
FROM scores
) usernames WHERE username NOTNULL;
第二和第三个用户名:
SELECT username
FROM (
SELECT unnest(ARRAY [(data #> '{scores,1,u}') :: TEXT, (data #> '{scores,2,u}') :: TEXT]) username
FROM scores
) usernames WHERE username NOTNULL;