3

I have a simple JSON array:

_bb jsonb =

[
  {
    "so": "1",
    "mdl": "Testing",
    "pos": "Top"
  },
  {
    "so": "1",
    "mdl": "FlashSale",
    "pos": "Bottom"
  },
  {
    "so": "1",
    "mdl": "Testing",
    "pos": "Top"
  }
]

What I want to achieve:

[
  {
    "so": "1",
    "mdl": "Testing",
    "pos": "Top"
  },
  {
    "so": "1",
    "mdl": "Testing",
    "pos": "Top"
  },
  {
    "so": "1",
    "mdl": "FlashSale",
    "pos": "Bottom"
  }
]

I tried doing

Select _bb  into _test  ORDER BY _bb->>'pos' ASC  ;

What I achieve is all the pos = "Top" be the first in the JSON and all the "Bottom" to be last. Is there a way to achieve this in Postgres?

Vao Tsun
  • 47,234
  • 13
  • 100
  • 132
Pickles
  • 243
  • 2
  • 3
  • 14
  • I dont understand how `ORDER BY _bb->>'pos' ASC ` would help to change the array index - can you share the structure?.. also in your original jsonb, `_bb[1]` is equal to `_bb[3]` - right?.. so what you say you have achieved is what you want then - no? – Vao Tsun Nov 02 '17 at 09:21
  • https://stackoverflow.com/questions/4088532/custom-order-by-explanation This should do the trick. You just have to convert it to your case – Doomenik Nov 02 '17 at 09:22
  • @VaoTsun Yea its _bb[3], but i would like to change the sort orders by placing "Top" as the priority to be first before "bottom". I'm not really too sure on what the syntax is to achieve it. – Pickles Nov 02 '17 at 09:23
  • alphabetically "bottom" is before "top" - are those two possible values or there can be more?.. – Vao Tsun Nov 02 '17 at 09:25
  • @VaoTsun there can be more like "Middle"... – Pickles Nov 02 '17 at 09:27

1 Answers1

3
with j(_bb) as (values('[
  {
    "so": "1",
    "mdl": "Testing",
    "pos": "Top"
  },
  {
    "so": "1",
    "mdl": "FlashSale",
    "pos": "Bottom"
  },
  {
    "so": "1",
    "mdl": "Testing",
    "pos": "Top"
  }
]'::jsonb))
, ord(o,v) as (values(1,'Top'),(2,'Bottom'))
, un as (select *,jsonb_array_elements(_bb) i from j)
select jsonb_agg(i order by o) from un
join ord on v=i->>'pos'
;

with result in:

[
  {
    "so": "1",
    "mdl": "Testing",
    "pos": "Top"
  },
  {
    "so": "1",
    "mdl": "Testing",
    "pos": "Top"
  },
  {
    "so": "1",
    "mdl": "FlashSale",
    "pos": "Bottom"
  }
]

needless to say you have to build order matrix for all values, eg:

, ord(o,v) as (values(1,'Top'),(2,'Middle'),(3,'Bottom'))

http://rextester.com/ZNDQ97753

Vao Tsun
  • 47,234
  • 13
  • 100
  • 132