简体   繁体   中英

Use json_array_elements(json) and get item ranks

I have a json made of two levels of arrays like :

[
  {
    name: "Group one",
    races: 
    [
     {name: "Race 1"},
     {name: "Race 2"},
    ]
  },
  {
    name: "Group two",
    races: 
    [
     {name: "Race 10"},
     {name: "Race 11"},
    ]
  }
]

Is it possible to get by magic SQL :

group_num | race_num | race
int       | int      | json
1         | 1        | {name: "Race 1"}
1         | 2        | {name: "Race 2"}
2         | 1        | {name: "Race 10"}
2         | 2        | {name: "Race 11"}

in which :

  • group_num is the rank of each group in its array
  • race_num is the rank of each race in its array

I presume this could have something to do with json_array_elements(json) and row_number() OVER () but I can't figure how to make it right !

with my_table(data) as (
values(
'[
  {
    "name": "Group one",
    "races": 
    [
     {"name": "Race 1"},
     {"name": "Race 2"}
    ]
  },
  {
    "name": "Group two",
    "races": 
    [
     {"name": "Race 10"},
     {"name": "Race 11"}
    ]
  }
]'::json)
)
select 
    group_num, 
    rank() over (partition by group_num order by value->>'name') as race_num,
    value as race
from (
    select 
        rank() over (order by value->>'name') as group_num, 
        value as grp
    from my_table,
    json_array_elements(data)
    ) s,
json_array_elements(grp->'races');

Results:

 group_num | race_num |        race         
-----------+----------+---------------------
         1 |        1 | {"name": "Race 1"}
         1 |        2 | {"name": "Race 2"}
         2 |        1 | {"name": "Race 10"}
         2 |        2 | {"name": "Race 11"}
(4 rows)    

Note, your json is invalid, use jsonlint to validate json expressions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM