2017-10-27 17 views
2

のクエリ特定の範囲私は現在、次の最も効率的な方法で解決を取得するために時間以来しようとしてPostgresqlの9.6を使用します。Postgresqlの9.6:JSONB配列

私の例テーブル:

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}]} 

I各行の上位2つのユーザー名(u)を取得するためのクエリが必要です。

だから私の結果は次のようになります。

users 
----- 
Peter 
Joe 
Mae 
Max 
Jack 
John 

そして、2番目と3番目のユーザ名を取得するためのクエリ:

users 
----- 
Joe 
Pam 
Max 
Moe 
John 
Wes 

これを解決する最も効率的な方法だろうか?私の実際のテーブルは100〜400要素と約1500行の配列を持っています。

+1

これを頻繁に行う必要がある場合は、通常の配列に関して[マニュアル](https://www.postgresql.org/docs/current/static/arrays.html)に記載されている助言について考えてみてください。 "*配列セットではありません。特定の配列要素を検索することは、データベースの誤った設計の兆候となります。配列要素となるアイテムごとに行を持つ別のテーブルを使用することを検討してください。これは検索が容易になり、多数の要素に対してよりスケーリングが容易になります* "これはJSONオブジェクト内に隠された配列にも当てはまります –

答えて

3

第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; 

2番目と3番目のユーザ名:

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; 

2番目と3番目のユーザ名:

SELECT username 
FROM (
    SELECT unnest(ARRAY [(data #> '{scores,1,u}') :: TEXT, (data #> '{scores,2,u}') :: TEXT]) username 
    FROM scores 
) usernames WHERE username NOTNULL; 
+0

恐ろしくありがとう - 本当に助けられました –

+0

ありがとう@Tomerこれはまさに私が逃したものでした。 – Smrchy

関連する問題